pinos -> pipewire

This commit is contained in:
Wim Taymans 2017-05-23 19:15:33 +02:00
parent f12a5ffc80
commit 83964cec87
197 changed files with 9430 additions and 11744 deletions

1
.gitignore vendored
View file

@ -7,5 +7,4 @@ ABOUT-NLS
*.tar.xz
*.o
config.h.meson
pkgconfig/libpinos-*.pc

View file

@ -1,3 +1,3 @@
All Pinos source files are licensed under the GNU Lesser General Public
All PipeWire source files are licensed under the GNU Lesser General Public
License. (see file LGPL for details)

View file

@ -8,6 +8,6 @@ clean:
ninja-build -C build clean
run:
PINOS_MODULE_DIR=build \
PINOS_CONFIG_FILE=build/pinos/daemon/pinos.conf \
build/pinos/daemon/pinos
PIPEWIRE_MODULE_DIR=build \
PIPEWIRE_CONFIG_FILE=build/pipewire/daemon/pipewire.conf \
build/pipewire/daemon/pipewire

2
NEWS
View file

@ -1 +1 @@
Pinos 0.1
PipeWire 0.1

17
README
View file

@ -1,12 +1,15 @@
Pinos
-----
PipeWire
--------
Pinos is a user space API to deal with video. This includes:
PipeWire is a server and user space API to deal with multimedia
pipelines. This includes:
- Make availabe sources of video (such as from a capture devices or
application provided streams)
application provided streams) and multiplexing this with
clients.
- Accessing sources of video for consumption.
- Generating graphs for audio and video processing
Video providers and consumers are implemented as separate processes
communicating with DBUS and exchanging video frames using fd passing.
Nodes in the graph can be implemented as separate processes,
communicating with sockets and exchanging multimedia content using fd
passing.

View file

@ -1,19 +1,19 @@
#!/bin/sh
# This file is part of Pinos
# This file is part of PipeWire
#
# Pinos is free software; you can redistribute it and/or modify it
# PipeWire is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Pinos is distributed in the hope that it will be useful, but
# PipeWire 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
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pinos; if not, see <http://www.gnu.org/licenses/>.
# along with PipeWire; if not, see <http://www.gnu.org/licenses/>.
# Only there to make jhbuild happy

View file

@ -364,7 +364,7 @@
#mesondefine MODULEDIR
/* directory where config files are located */
#mesondefine PINOS_CONFIG_DIR
#mesondefine PIPEWIRE_CONFIG_DIR
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */

1
doc/.gitignore vendored
View file

@ -1 +0,0 @@
org-pinos-*.xml

View file

@ -1,5 +1,5 @@
Pinos
-----
PipeWire
--------
The idea is to make a server where you can provide
and consume media to/from.

8
man/.gitignore vendored
View file

@ -1,4 +1,4 @@
pinos-monitor.1
pinos-monitor.1.xml
pinos.1
pinos.1.xml
pipewire-monitor.1
pipewire-monitor.1.xml
pipewire.1
pipewire.1.xml

View file

@ -3,30 +3,30 @@
<?xml-stylesheet type="text/xsl" href="xmltoman.xsl" ?>
<!--
This file is part of Pinos.
This file is part of PipeWire.
Pinos is free software; you can redistribute it and/or modify it
PipeWire is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
Pinos is distributed in the hope that it will be useful, but WITHOUT
PipeWire 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 Lesser General
Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Pinos; if not, see <http://www.gnu.org/licenses/>.
License along with PipeWire; if not, see <http://www.gnu.org/licenses/>.
-->
<manpage name="pinos-monitor" section="1" desc="The Pinos monitor">
<manpage name="pipewire-monitor" section="1" desc="The PipeWire monitor">
<synopsis>
<cmd>pinos</cmd>
<cmd>pipewire</cmd>
</synopsis>
<description>
<p>Monitor objects on the Pinos service.</p>
<p>Monitor objects on the PipeWire service.</p>
</description>
<options>
@ -46,12 +46,12 @@ License along with Pinos; if not, see <http://www.gnu.org/licenses/>.
</options>
<section name="Authors">
<p>The Pinos Developers &lt;@PACKAGE_BUGREPORT@&gt;; Pinos is available from <url href="@PACKAGE_URL@"/></p>
<p>The PipeWire Developers &lt;@PACKAGE_BUGREPORT@&gt;; PipeWire is available from <url href="@PACKAGE_URL@"/></p>
</section>
<section name="See also">
<p>
<manref name="pinos" section="1"/>,
<manref name="pipewire" section="1"/>,
</p>
</section>

View file

@ -3,30 +3,30 @@
<?xml-stylesheet type="text/xsl" href="xmltoman.xsl" ?>
<!--
This file is part of Pinos.
This file is part of PipeWire.
Pinos is free software; you can redistribute it and/or modify it
PipeWire is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
Pinos is distributed in the hope that it will be useful, but WITHOUT
PipeWire 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 Lesser General
Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Pinos; if not, see <http://www.gnu.org/licenses/>.
License along with PipeWire; if not, see <http://www.gnu.org/licenses/>.
-->
<manpage name="pinos" section="1" desc="The Pinos media server">
<manpage name="pipewire" section="1" desc="The PipeWire media server">
<synopsis>
<cmd>pinos</cmd>
<cmd>pipewire</cmd>
</synopsis>
<description>
<p>Pinos is a DBus service that allows access to multimedia devices
<p>PipeWire is a service that allows access to multimedia devices
and allows media sharing between applications. </p>
</description>
@ -47,12 +47,12 @@ License along with Pinos; if not, see <http://www.gnu.org/licenses/>.
</options>
<section name="Authors">
<p>The Pinos Developers &lt;@PACKAGE_BUGREPORT@&gt;; Pinos is available from <url href="@PACKAGE_URL@"/></p>
<p>The PipeWire Developers &lt;@PACKAGE_BUGREPORT@&gt;; PipeWire is available from <url href="@PACKAGE_URL@"/></p>
</section>
<section name="See also">
<p>
<manref name="pinos-monitor" section="1"/>,
<manref name="pipewire-monitor" section="1"/>,
</p>
</section>

View file

@ -1,18 +1,18 @@
/***
This file is part of Pinos.
This file is part of PipeWire.
Pinos is free software; you can redistribute it and/or modify it under
PipeWire is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
Pinos is distributed in the hope that it will be useful, but WITHOUT
PipeWire 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 General Public License
for more details.
You should have received a copy of the GNU General Public License
along with Pinos; if not, see <http://www.gnu.org/licenses/>.
along with PipeWire; if not, see <http://www.gnu.org/licenses/>.
***/
body { color: black; background-color: white; }

View file

@ -1,18 +1,18 @@
<!--
This file is part of Pinos.
This file is part of PipeWire.
Pinos is free software; you can redistribute it and/or modify it under
PipeWire is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
Pinos is distributed in the hope that it will be useful, but WITHOUT
PipeWire 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 General Public License
for more details.
You should have received a copy of the GNU General Public License
along with Pinos; if not, see <http://www.gnu.org/licenses/>.
along with PipeWire; if not, see <http://www.gnu.org/licenses/>.
-->
<!ELEMENT manpage (synopsis | description | section | options | seealso)*>

View file

@ -2,20 +2,20 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<!--
This file is part of Pinos.
This file is part of PipeWire.
Pinos is free software; you can redistribute it and/or modify it under
PipeWire is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
Pinos is distributed in the hope that it will be useful, but WITHOUT
PipeWire 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 General Public License
for more details.
You should have received a copy of the GNU General Public License
along with Pinos; if not, see <http://www.gnu.org/licenses/>.
along with PipeWire; if not, see <http://www.gnu.org/licenses/>.
-->
<xsl:output method="xml" version="1.0" encoding="iso-8859-15" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" indent="yes"/>

View file

@ -1,4 +1,4 @@
project('pinos', 'c',
project('pipewire', 'c',
version : '0.0.1.1',
meson_version : '>= 0.36.0',
default_options : [ 'warning_level=1',
@ -6,24 +6,24 @@ project('pinos', 'c',
'buildtype=debugoptimized' ])
pinos_version = meson.project_version()
version_arr = pinos_version.split('.')
pinos_version_major = version_arr[0]
pinos_version_minor = version_arr[1]
pinos_version_micro = version_arr[2]
pipewire_version = meson.project_version()
version_arr = pipewire_version.split('.')
pipewire_version_major = version_arr[0]
pipewire_version_minor = version_arr[1]
pipewire_version_micro = version_arr[2]
if version_arr.length() == 4
pinos_version_nano = version_arr[3]
pipewire_version_nano = version_arr[3]
else
pinos_version_nano = 0
pipewire_version_nano = 0
endif
apiversion = '0.1'
soversion = 0
libversion = '@0@.@1@.0'.format(soversion, pinos_version_minor.to_int() * 100 + pinos_version_micro.to_int())
libversion = '@0@.@1@.0'.format(soversion, pipewire_version_minor.to_int() * 100 + pipewire_version_micro.to_int())
prefix = get_option('prefix')
modules_install_dir = '@0@/pinos-@1@'.format(get_option('libdir'), apiversion)
modules_install_dir = '@0@/pipewire-@1@'.format(get_option('libdir'), apiversion)
gnome = import('gnome')
@ -31,27 +31,27 @@ cc = meson.get_compiler('c')
cdata = configuration_data()
cdata.set('PINOS_VERSION_MAJOR', pinos_version_major)
cdata.set('PINOS_VERSION_MINOR', pinos_version_minor)
cdata.set('PINOS_VERSION_MICRO', pinos_version_micro)
cdata.set('PINOS_VERSION_NANO', pinos_version_nano)
cdata.set('PINOS_API_VERSION', '"@0@"'.format(apiversion))
cdata.set('PINOS_DATADIR', '"@0@/@1@"'.format(prefix, get_option('datadir')))
cdata.set('PIPEWIRE_VERSION_MAJOR', pipewire_version_major)
cdata.set('PIPEWIRE_VERSION_MINOR', pipewire_version_minor)
cdata.set('PIPEWIRE_VERSION_MICRO', pipewire_version_micro)
cdata.set('PIPEWIRE_VERSION_NANO', pipewire_version_nano)
cdata.set('PIPEWIRE_API_VERSION', '"@0@"'.format(apiversion))
cdata.set('PIPEWIRE_DATADIR', '"@0@/@1@"'.format(prefix, get_option('datadir')))
cdata.set('LOCALEDIR', '"@0@/@1@"'.format(prefix, get_option('localedir')))
cdata.set('LIBDIR', '"@0@/@1@"'.format(prefix, get_option('libdir')))
cdata.set('GETTEXT_PACKAGE', '"pinos"')
cdata.set('PINOS_LICENSE', '"LGPL"')
cdata.set('PINOS_PACKAGE_ORIGIN', '"Unknown package origin"')
cdata.set('PINOS_PACKAGE_NAME', '"Pinos source release"')
cdata.set('PACKAGE', '"pinos"')
cdata.set('PACKAGE_NAME', '"Pinos"')
cdata.set('PACKAGE_STRING', '"Pinos @0@"'.format(pinos_version))
cdata.set('PACKAGE_TARNAME', '"pinos"')
cdata.set('GETTEXT_PACKAGE', '"pipewire"')
cdata.set('PIPEWIRE_LICENSE', '"LGPL"')
cdata.set('PIPEWIRE_PACKAGE_ORIGIN', '"Unknown package origin"')
cdata.set('PIPEWIRE_PACKAGE_NAME', '"PipeWire source release"')
cdata.set('PACKAGE', '"pipewire"')
cdata.set('PACKAGE_NAME', '"PipeWire"')
cdata.set('PACKAGE_STRING', '"PipeWire @0@"'.format(pipewire_version))
cdata.set('PACKAGE_TARNAME', '"pipewire"')
cdata.set('PACKAGE_URL', '""')
cdata.set('PACKAGE_VERSION', '"@0@"'.format(pinos_version))
cdata.set('MODULEDIR', '"@0@/@1@/pinos-@2@"'.format(get_option('prefix'),get_option('libdir'),apiversion))
cdata.set('PINOS_CONFIG_DIR', '"@0@/pinos"'.format(join_paths(get_option('prefix'), get_option('sysconfdir'))))
cdata.set('VERSION', '"@0@"'.format(pinos_version))
cdata.set('PACKAGE_VERSION', '"@0@"'.format(pipewire_version))
cdata.set('MODULEDIR', '"@0@/@1@/pipewire-@2@"'.format(get_option('prefix'),get_option('libdir'),apiversion))
cdata.set('PIPEWIRE_CONFIG_DIR', '"@0@/pipewire"'.format(join_paths(get_option('prefix'), get_option('sysconfdir'))))
cdata.set('VERSION', '"@0@"'.format(pipewire_version))
# FIXME: --with-memory-alignment],[8,N,malloc,pagesize (default is 32)]) option
cdata.set('MEMORY_ALIGNMENT_MALLOC', 1)
@ -134,7 +134,7 @@ gst_dep = [dependency('gstreamer-1.0'),
dependency('gstreamer-allocators-1.0'),]
subdir('spa')
subdir('pinos')
subdir('pipewire')
subdir('pkgconfig')
#gtkdoc = find_program('gtkdoc-scan', required : false)

3
pinos/.gitignore vendored
View file

@ -1,3 +0,0 @@
pinos
test-client
pinos-monitor

View file

@ -1,69 +0,0 @@
/* Pinos
* Copyright (C) 2016 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.
*/
#ifndef __PINOS_CONNECTION_H__
#define __PINOS_CONNECTION_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/defs.h>
#include <pinos/client/sig.h>
typedef struct _PinosConnection PinosConnection;
struct _PinosConnection {
int fd;
PINOS_SIGNAL (need_flush, (PinosListener *listener,
PinosConnection *conn));
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosConnection *conn));
};
PinosConnection * pinos_connection_new (int fd);
void pinos_connection_destroy (PinosConnection *conn);
uint32_t pinos_connection_add_fd (PinosConnection *conn,
int fd);
int pinos_connection_get_fd (PinosConnection *conn,
uint32_t index);
bool pinos_connection_get_next (PinosConnection *conn,
uint8_t *opcode,
uint32_t *dest_id,
void **data,
uint32_t *size);
void * pinos_connection_begin_write (PinosConnection *conn,
uint32_t size);
void pinos_connection_end_write (PinosConnection *conn,
uint32_t dest_id,
uint8_t opcode,
uint32_t size);
bool pinos_connection_flush (PinosConnection *conn);
bool pinos_connection_clear (PinosConnection *conn);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __PINOS_CONNECTION_H__ */

View file

@ -1,877 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include "pinos/client/pinos.h"
#include "pinos/client/context.h"
#include "pinos/client/protocol-native.h"
#include "pinos/client/connection.h"
#include "pinos/client/subscribe.h"
typedef struct {
PinosContext this;
bool no_proxy;
int fd;
PinosConnection *connection;
SpaSource *source;
bool disconnecting;
PinosListener need_flush;
SpaSource *flush_event;
} PinosContextImpl;
/**
* pinos_context_state_as_string:
* @state: a #PinosContextState
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *
pinos_context_state_as_string (PinosContextState state)
{
switch (state) {
case PINOS_CONTEXT_STATE_ERROR:
return "error";
case PINOS_CONTEXT_STATE_UNCONNECTED:
return "unconnected";
case PINOS_CONTEXT_STATE_CONNECTING:
return "connecting";
case PINOS_CONTEXT_STATE_CONNECTED:
return "connected";
}
return "invalid-state";
}
static void
context_set_state (PinosContext *context,
PinosContextState state,
const char *fmt,
...)
{
if (context->state != state) {
if (context->error)
free (context->error);
if (fmt) {
va_list varargs;
va_start (varargs, fmt);
vasprintf (&context->error, fmt, varargs);
va_end (varargs);
} else {
context->error = NULL;
}
pinos_log_debug ("context %p: update state from %s -> %s (%s)", context,
pinos_context_state_as_string (context->state),
pinos_context_state_as_string (state),
context->error);
context->state = state;
pinos_signal_emit (&context->state_changed, context);
}
}
static void
core_event_info (void *object,
PinosCoreInfo *info)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
PinosSubscriptionEvent event;
pinos_log_debug ("got core info");
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_core_info_update (proxy->user_data, info);
pinos_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static void
core_event_done (void *object,
uint32_t seq)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
if (seq == 0) {
pinos_core_do_sync (this->core_proxy, 1);
} else if (seq == 1) {
context_set_state (this, PINOS_CONTEXT_STATE_CONNECTED, NULL);
}
}
static void
core_event_error (void *object,
uint32_t id,
SpaResult res,
const char *error, ...)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
context_set_state (this, PINOS_CONTEXT_STATE_ERROR, error);
}
static void
core_event_remove_id (void *object,
uint32_t id)
{
PinosProxy *core_proxy = object;
PinosContext *this = core_proxy->context;
PinosProxy *proxy;
proxy = pinos_map_lookup (&this->objects, id);
if (proxy) {
pinos_log_debug ("context %p: object remove %u", this, id);
pinos_proxy_destroy (proxy);
}
}
static void
core_event_update_types (void *object,
uint32_t first_id,
uint32_t n_types,
const char **types)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
int i;
for (i = 0; i < n_types; i++, first_id++) {
SpaType this_id = spa_type_map_get_id (this->type.map, types[i]);
if (!pinos_map_insert_at (&this->types, first_id, PINOS_MAP_ID_TO_PTR (this_id)))
pinos_log_error ("can't add type for client");
}
}
static const PinosCoreEvents core_events = {
&core_event_info,
&core_event_done,
&core_event_error,
&core_event_remove_id,
&core_event_update_types
};
static void
module_event_info (void *object,
PinosModuleInfo *info)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
PinosSubscriptionEvent event;
pinos_log_debug ("got module info");
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_module_info_update (proxy->user_data, info);
pinos_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const PinosModuleEvents module_events = {
&module_event_info,
};
static void
node_event_info (void *object,
PinosNodeInfo *info)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
PinosSubscriptionEvent event;
pinos_log_debug ("got node info");
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_node_info_update (proxy->user_data, info);
pinos_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const PinosNodeEvents node_events = {
&node_event_info
};
static void
client_event_info (void *object,
PinosClientInfo *info)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
PinosSubscriptionEvent event;
pinos_log_debug ("got client info");
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_client_info_update (proxy->user_data, info);
pinos_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const PinosClientEvents client_events = {
&client_event_info
};
static void
link_event_info (void *object,
PinosLinkInfo *info)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
PinosSubscriptionEvent event;
pinos_log_debug ("got link info");
if (proxy->user_data == NULL)
event = PINOS_SUBSCRIPTION_EVENT_NEW;
else
event = PINOS_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pinos_link_info_update (proxy->user_data, info);
pinos_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const PinosLinkEvents link_events = {
&link_event_info
};
static void
registry_event_global (void *object,
uint32_t id,
const char *type)
{
PinosProxy *registry_proxy = object;
PinosContext *this = registry_proxy->context;
PinosContextImpl *impl = SPA_CONTAINER_OF (this, PinosContextImpl, this);
PinosProxy *proxy = NULL;
if (impl->no_proxy)
return;
pinos_log_debug ("got global %u %s", id, type);
if (!strcmp (type, PINOS_TYPE__Node)) {
proxy = pinos_proxy_new (this,
SPA_ID_INVALID,
this->type.node);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &node_events;
} else if (!strcmp (type, PINOS_TYPE__Module)) {
proxy = pinos_proxy_new (this,
SPA_ID_INVALID,
this->type.module);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &module_events;
} else if (!strcmp (type, PINOS_TYPE__Client)) {
proxy = pinos_proxy_new (this,
SPA_ID_INVALID,
this->type.client);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &client_events;
} else if (!strcmp (type, PINOS_TYPE__Link)) {
proxy = pinos_proxy_new (this,
SPA_ID_INVALID,
this->type.link);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &link_events;
}
if (proxy) {
pinos_registry_do_bind (registry_proxy, id, proxy->id);
}
return;
no_mem:
pinos_log_error ("context %p: failed to create proxy", this);
return;
}
static void
registry_event_global_remove (void *object,
uint32_t id)
{
PinosProxy *proxy = object;
PinosContext *this = proxy->context;
pinos_log_debug ("got global remove %u", id);
pinos_signal_emit (&this->subscription,
this,
PINOS_SUBSCRIPTION_EVENT_REMOVE,
SPA_ID_INVALID,
id);
}
static const PinosRegistryEvents registry_events = {
&registry_event_global,
&registry_event_global_remove
};
typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size);
static void
do_flush_event (SpaLoopUtils *utils,
SpaSource *source,
void *data)
{
PinosContextImpl *impl = data;
if (impl->connection)
if (!pinos_connection_flush (impl->connection))
pinos_context_disconnect (&impl->this);
}
static void
on_need_flush (PinosListener *listener,
PinosConnection *connection)
{
PinosContextImpl *impl = SPA_CONTAINER_OF (listener, PinosContextImpl, need_flush);
PinosContext *this = &impl->this;
pinos_loop_signal_event (this->loop, impl->flush_event);
}
static void
on_context_data (SpaLoopUtils *utils,
SpaSource *source,
int fd,
SpaIO mask,
void *data)
{
PinosContextImpl *impl = data;
PinosContext *this = &impl->this;
PinosConnection *conn = impl->connection;
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
context_set_state (this,
PINOS_CONTEXT_STATE_ERROR,
"connection closed");
return;
}
if (mask & SPA_IO_IN) {
uint8_t opcode;
uint32_t id;
uint32_t size;
void *message;
while (!impl->disconnecting
&& pinos_connection_get_next (conn, &opcode, &id, &message, &size)) {
PinosProxy *proxy;
const PinosDemarshalFunc *demarshal;
pinos_log_trace ("context %p: got message %d from %u", this, opcode, id);
proxy = pinos_map_lookup (&this->objects, id);
if (proxy == NULL) {
pinos_log_error ("context %p: could not find proxy %u", this, id);
continue;
}
if (opcode >= proxy->iface->n_events) {
pinos_log_error ("context %p: invalid method %u for %u", this, opcode, id);
continue;
}
demarshal = proxy->iface->events;
if (demarshal[opcode]) {
if (!demarshal[opcode] (proxy, message, size))
pinos_log_error ("context %p: invalid message received %u for %u", this, opcode, id);
} else
pinos_log_error ("context %p: function %d not implemented on %u", this, opcode, id);
}
}
}
/**
* pinos_context_new:
* @context: a #GMainContext to run in
* @name: an application name
* @properties: (transfer full): optional properties
*
* Make a new unconnected #PinosContext
*
* Returns: a new unconnected #PinosContext
*/
PinosContext *
pinos_context_new (PinosLoop *loop,
const char *name,
PinosProperties *properties)
{
PinosContextImpl *impl;
PinosContext *this;
impl = calloc (1, sizeof (PinosContextImpl));
if (impl == NULL)
return NULL;
impl->fd = -1;
this = &impl->this;
pinos_log_debug ("context %p: new", impl);
this->name = strdup (name);
if (properties == NULL)
properties = pinos_properties_new ("application.name", name, NULL);
if (properties == NULL)
goto no_mem;
pinos_fill_context_properties (properties);
this->properties = properties;
pinos_type_init (&this->type);
this->loop = loop;
impl->flush_event = pinos_loop_add_event (loop, do_flush_event, impl);
this->state = PINOS_CONTEXT_STATE_UNCONNECTED;
pinos_map_init (&this->objects, 64, 32);
pinos_map_init (&this->types, 64, 32);
spa_list_init (&this->stream_list);
spa_list_init (&this->global_list);
spa_list_init (&this->proxy_list);
pinos_signal_init (&this->state_changed);
pinos_signal_init (&this->subscription);
pinos_signal_init (&this->destroy_signal);
return this;
no_mem:
free (this->name);
free (impl);
return NULL;
}
void
pinos_context_destroy (PinosContext *context)
{
PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
PinosStream *stream, *t1;
PinosProxy *proxy, *t2;
pinos_log_debug ("context %p: destroy", context);
pinos_signal_emit (&context->destroy_signal, context);
pinos_loop_destroy_source (impl->this.loop, impl->flush_event);
if (context->state != PINOS_CONTEXT_STATE_UNCONNECTED)
pinos_context_disconnect (context);
spa_list_for_each_safe (stream, t1, &context->stream_list, link)
pinos_stream_destroy (stream);
spa_list_for_each_safe (proxy, t2, &context->proxy_list, link)
pinos_proxy_destroy (proxy);
pinos_map_clear (&context->objects);
free (context->name);
if (context->properties)
pinos_properties_free (context->properties);
free (context->error);
free (impl);
}
/**
* pinos_context_connect:
* @context: a #PinosContext
*
* Connect to the daemon
*
* Returns: %TRUE on success.
*/
bool
pinos_context_connect (PinosContext *context,
PinosContextFlags flags)
{
struct sockaddr_un addr;
socklen_t size;
const char *runtime_dir, *name = NULL;
int name_size, fd;
if ((runtime_dir = getenv ("XDG_RUNTIME_DIR")) == NULL) {
context_set_state (context,
PINOS_CONTEXT_STATE_ERROR,
"connect failed: XDG_RUNTIME_DIR not set in the environment");
return false;
}
if (name == NULL)
name = getenv("PINOS_CORE");
if (name == NULL)
name = "pinos-0";
if ((fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0)
return false;
memset (&addr, 0, sizeof (addr));
addr.sun_family = AF_LOCAL;
name_size = snprintf (addr.sun_path, sizeof (addr.sun_path),
"%s/%s", runtime_dir, name) + 1;
if (name_size > (int)sizeof addr.sun_path) {
pinos_log_error ("socket path \"%s/%s\" plus null terminator exceeds 108 bytes",
runtime_dir, name);
goto error_close;
};
size = offsetof (struct sockaddr_un, sun_path) + name_size;
if (connect (fd, (struct sockaddr *) &addr, size) < 0) {
context_set_state (context,
PINOS_CONTEXT_STATE_ERROR,
"connect failed: %s", strerror (errno));
goto error_close;
}
return pinos_context_connect_fd (context, flags, fd);
error_close:
close (fd);
return false;
}
/**
* pinos_context_connect_fd:
* @context: a #PinosContext
* @fd: FD of a connected Pinos socket
*
* Connect to a daemon. @fd should already be connected to a Pinos socket.
*
* Returns: %TRUE on success.
*/
bool
pinos_context_connect_fd (PinosContext *context,
PinosContextFlags flags,
int fd)
{
PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
context_set_state (context, PINOS_CONTEXT_STATE_CONNECTING, NULL);
impl->connection = pinos_connection_new (fd);
if (impl->connection == NULL)
goto error_close;
context->protocol_private = impl->connection;
pinos_signal_add (&impl->connection->need_flush,
&impl->need_flush,
on_need_flush);
impl->fd = fd;
impl->source = pinos_loop_add_io (context->loop,
fd,
SPA_IO_IN | SPA_IO_HUP | SPA_IO_ERR,
false,
on_context_data,
impl);
context->core_proxy = pinos_proxy_new (context,
0,
context->type.core);
if (context->core_proxy == NULL)
goto no_proxy;
context->core_proxy->implementation = &core_events;
pinos_core_do_client_update (context->core_proxy,
&context->properties->dict);
if (!(flags & PINOS_CONTEXT_FLAG_NO_REGISTRY)) {
context->registry_proxy = pinos_proxy_new (context,
SPA_ID_INVALID,
context->type.registry);
if (context->registry_proxy == NULL)
goto no_registry;
context->registry_proxy->implementation = &registry_events;
pinos_core_do_get_registry (context->core_proxy,
context->registry_proxy->id);
}
impl->no_proxy = !!(flags & PINOS_CONTEXT_FLAG_NO_PROXY);
pinos_core_do_sync (context->core_proxy, 0);
return true;
no_registry:
pinos_proxy_destroy (context->core_proxy);
no_proxy:
pinos_loop_destroy_source (context->loop, impl->source);
pinos_connection_destroy (impl->connection);
error_close:
close (fd);
return false;
}
/**
* pinos_context_disconnect:
* @context: a #PinosContext
*
* Disonnect from the daemon.
*
* Returns: %TRUE on success.
*/
bool
pinos_context_disconnect (PinosContext *context)
{
PinosContextImpl *impl = SPA_CONTAINER_OF (context, PinosContextImpl, this);
impl->disconnecting = true;
if (impl->source)
pinos_loop_destroy_source (context->loop, impl->source);
impl->source = NULL;
if (context->registry_proxy)
pinos_proxy_destroy (context->registry_proxy);
context->registry_proxy = NULL;
if (context->core_proxy)
pinos_proxy_destroy (context->core_proxy);
context->core_proxy = NULL;
if (impl->connection)
pinos_connection_destroy (impl->connection);
impl->connection = NULL;
context->protocol_private = NULL;
if (impl->fd != -1)
close (impl->fd);
impl->fd = -1;
context_set_state (context, PINOS_CONTEXT_STATE_UNCONNECTED, NULL);
return true;
}
void
pinos_context_get_core_info (PinosContext *context,
PinosCoreInfoCallback cb,
void *user_data)
{
PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, 0);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.core && proxy->user_data) {
PinosCoreInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
typedef void (*ListFunc) (PinosContext *, SpaResult, void *, void *);
static void
do_list (PinosContext *context,
uint32_t type,
ListFunc cb,
void *user_data)
{
PinosMapItem *item;
pinos_array_for_each (item, &context->objects.items) {
PinosProxy *proxy;
if (pinos_map_item_is_free (item))
continue;
proxy = item->data;
if (proxy->type != type)
continue;
if (proxy->user_data)
cb (context, SPA_RESULT_OK, proxy->user_data, user_data);
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pinos_context_list_module_info (PinosContext *context,
PinosModuleInfoCallback cb,
void *user_data)
{
do_list (context, context->type.module, (ListFunc) cb, user_data);
}
void
pinos_context_get_module_info_by_id (PinosContext *context,
uint32_t id,
PinosModuleInfoCallback cb,
void *user_data)
{
PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.module && proxy->user_data) {
PinosModuleInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pinos_context_list_client_info (PinosContext *context,
PinosClientInfoCallback cb,
void *user_data)
{
do_list (context, context->type.client, (ListFunc) cb, user_data);
}
void
pinos_context_get_client_info_by_id (PinosContext *context,
uint32_t id,
PinosClientInfoCallback cb,
void *user_data)
{
PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.client && proxy->user_data) {
PinosClientInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pinos_context_list_node_info (PinosContext *context,
PinosNodeInfoCallback cb,
void *user_data)
{
do_list (context, context->type.node, (ListFunc) cb, user_data);
}
void
pinos_context_get_node_info_by_id (PinosContext *context,
uint32_t id,
PinosNodeInfoCallback cb,
void *user_data)
{
PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.node && proxy->user_data) {
PinosNodeInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pinos_context_list_link_info (PinosContext *context,
PinosLinkInfoCallback cb,
void *user_data)
{
do_list (context, context->type.link, (ListFunc) cb, user_data);
}
void
pinos_context_get_link_info_by_id (PinosContext *context,
uint32_t id,
PinosLinkInfoCallback cb,
void *user_data)
{
PinosProxy *proxy;
proxy = pinos_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.link && proxy->user_data) {
PinosLinkInfo *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}

View file

@ -1,117 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_CONTEXT_H__
#define __PINOS_CONTEXT_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosContext PinosContext;
#include <pinos/client/map.h>
#include <pinos/client/loop.h>
#include <pinos/client/properties.h>
#include <pinos/client/subscribe.h>
#include <pinos/client/proxy.h>
#include <pinos/client/type.h>
/**
* PinosContextState:
* @PINOS_CONTEXT_STATE_ERROR: context is in error
* @PINOS_CONTEXT_STATE_UNCONNECTED: not connected
* @PINOS_CONTEXT_STATE_CONNECTING: connecting to daemon
* @PINOS_CONTEXT_STATE_CONNECTED: context is connected and ready
*
* The state of a #PinosContext
*/
typedef enum {
PINOS_CONTEXT_STATE_ERROR = -1,
PINOS_CONTEXT_STATE_UNCONNECTED = 0,
PINOS_CONTEXT_STATE_CONNECTING = 1,
PINOS_CONTEXT_STATE_CONNECTED = 2,
} PinosContextState;
typedef enum {
PINOS_CONTEXT_FLAG_NONE = 0,
PINOS_CONTEXT_FLAG_NO_REGISTRY = (1 << 0),
PINOS_CONTEXT_FLAG_NO_PROXY = (1 << 1),
} PinosContextFlags;
const char * pinos_context_state_as_string (PinosContextState state);
/**
* PinosContext:
*
* Pinos context object class.
*/
struct _PinosContext {
char *name;
PinosProperties *properties;
PinosType type;
PinosLoop *loop;
PinosProxy *core_proxy;
PinosProxy *registry_proxy;
PinosMap objects;
uint32_t n_types;
PinosMap types;
SpaList global_list;
SpaList stream_list;
SpaList proxy_list;
void *protocol_private;
PinosContextState state;
char *error;
PINOS_SIGNAL (state_changed, (PinosListener *listener,
PinosContext *context));
PINOS_SIGNAL (subscription, (PinosListener *listener,
PinosContext *context,
PinosSubscriptionEvent event,
uint32_t type,
uint32_t id));
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosContext *context));
};
PinosContext * pinos_context_new (PinosLoop *loop,
const char *name,
PinosProperties *properties);
void pinos_context_destroy (PinosContext *context);
bool pinos_context_connect (PinosContext *context,
PinosContextFlags flags);
bool pinos_context_connect_fd (PinosContext *context,
PinosContextFlags flags,
int fd);
bool pinos_context_disconnect (PinosContext *context);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_CONTEXT_H__ */

View file

@ -1,348 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_INTROSPECT_H__
#define __PINOS_INTROSPECT_H__
#include <spa/defs.h>
#include <spa/format.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum _PinosNodeState PinosNodeState;
typedef enum _PinosDirection PinosDirection;
typedef enum _PinosLinkState PinosLinkState;
typedef struct _PinosCoreInfo PinosCoreInfo;
typedef struct _PinosModuleInfo PinosModuleInfo;
typedef struct _PinosClientInfo PinosClientInfo;
typedef struct _PinosNodeInfo PinosNodeInfo;
typedef struct _PinosLinkInfo PinosLinkInfo;
#include <pinos/client/context.h>
#include <pinos/client/properties.h>
/**
* PinosNodeState:
* @PINOS_NODE_STATE_ERROR: the node is in error
* @PINOS_NODE_STATE_CREATING: the node is being created
* @PINOS_NODE_STATE_SUSPENDED: the node is suspended, the device might
* be closed
* @PINOS_NODE_STATE_IDLE: the node is running but there is no active
* port
* @PINOS_NODE_STATE_RUNNING: the node is running
*
* The different node states
*/
enum _PinosNodeState {
PINOS_NODE_STATE_ERROR = -1,
PINOS_NODE_STATE_CREATING = 0,
PINOS_NODE_STATE_SUSPENDED = 1,
PINOS_NODE_STATE_IDLE = 2,
PINOS_NODE_STATE_RUNNING = 3,
};
const char * pinos_node_state_as_string (PinosNodeState state);
/**
* PinosDirection:
* @PINOS_DIRECTION_INVALID: invalid direction
* @PINOS_DIRECTION_INPUT: an input port
* @PINOS_DIRECTION_OUTPUT: an output port
*
* The direction of a port
*/
enum _PinosDirection {
PINOS_DIRECTION_INPUT = SPA_DIRECTION_INPUT,
PINOS_DIRECTION_OUTPUT = SPA_DIRECTION_OUTPUT
};
const char * pinos_direction_as_string (PinosDirection direction);
/**
* PinosLinkState:
* @PINOS_LINK_STATE_ERROR: the link is in error
* @PINOS_LINK_STATE_UNLINKED: the link is unlinked
* @PINOS_LINK_STATE_INIT: the link is initialized
* @PINOS_LINK_STATE_NEGOTIATING: the link is negotiating formats
* @PINOS_LINK_STATE_ALLOCATING: the link is allocating buffers
* @PINOS_LINK_STATE_PAUSED: the link is paused
* @PINOS_LINK_STATE_RUNNING: the link is running
*
* The different link states
*/
enum _PinosLinkState {
PINOS_LINK_STATE_ERROR = -2,
PINOS_LINK_STATE_UNLINKED = -1,
PINOS_LINK_STATE_INIT = 0,
PINOS_LINK_STATE_NEGOTIATING = 1,
PINOS_LINK_STATE_ALLOCATING = 2,
PINOS_LINK_STATE_PAUSED = 3,
PINOS_LINK_STATE_RUNNING = 4,
};
const char * pinos_link_state_as_string (PinosLinkState state);
/**
* PinosCoreInfo:
* @id: generic id of the core
* @change_mask: bitfield of changed fields since last call
* @user_name: name of the user that started the core
* @host_name: name of the machine the core is running on
* @version: version of the core
* @name: name of the core
* @cookie: a random cookie for identifying this instance of Pinos
* @props: extra properties
*
* The core information. Extra information can be added in later
* versions.
*/
struct _PinosCoreInfo {
uint32_t id;
uint64_t change_mask;
#define PINOS_CORE_CHANGE_MASK_USER_NAME (1 << 0)
#define PINOS_CORE_CHANGE_MASK_HOST_NAME (1 << 1)
#define PINOS_CORE_CHANGE_MASK_VERSION (1 << 2)
#define PINOS_CORE_CHANGE_MASK_NAME (1 << 3)
#define PINOS_CORE_CHANGE_MASK_COOKIE (1 << 4)
#define PINOS_CORE_CHANGE_MASK_PROPS (1 << 5)
#define PINOS_CORE_CHANGE_MASK_ALL (~0)
const char *user_name;
const char *host_name;
const char *version;
const char *name;
uint32_t cookie;
SpaDict *props;
};
PinosCoreInfo * pinos_core_info_update (PinosCoreInfo *info,
const PinosCoreInfo *update);
void pinos_core_info_free (PinosCoreInfo *info);
/**
* PinosCoreInfoCallback:
* @c: a #PinosContext
* @info: a #PinosCoreInfo
* @user_data: user data
*
* Callback with information about the Pinos core in @info.
*/
typedef void (*PinosCoreInfoCallback) (PinosContext *c,
SpaResult res,
const PinosCoreInfo *info,
void *user_data);
void pinos_context_get_core_info (PinosContext *context,
PinosCoreInfoCallback cb,
void *user_data);
/**
* PinosModuleInfo:
* @id: generic id of the module
* @change_mask: bitfield of changed fields since last call
* @props: extra properties
*
* The module information. Extra information can be added in later
* versions.
*/
struct _PinosModuleInfo {
uint32_t id;
uint64_t change_mask;
const char *name;
const char *filename;
const char *args;
SpaDict *props;
};
PinosModuleInfo * pinos_module_info_update (PinosModuleInfo *info,
const PinosModuleInfo *update);
void pinos_module_info_free (PinosModuleInfo *info);
/**
* PinosModuleInfoCallback:
* @c: a #PinosContext
* @info: a #PinosModuleInfo
* @user_data: user data
*
* Callback with information about the Pinos module in @info.
*/
typedef void (*PinosModuleInfoCallback) (PinosContext *c,
SpaResult res,
const PinosModuleInfo *info,
void *user_data);
void pinos_context_list_module_info (PinosContext *context,
PinosModuleInfoCallback cb,
void *user_data);
void pinos_context_get_module_info_by_id (PinosContext *context,
uint32_t id,
PinosModuleInfoCallback cb,
void *user_data);
/**
* PinosClientInfo:
* @id: generic id of the client
* @change_mask: bitfield of changed fields since last call
* @props: extra properties
*
* The client information. Extra information can be added in later
* versions.
*/
struct _PinosClientInfo {
uint32_t id;
uint64_t change_mask;
SpaDict *props;
};
PinosClientInfo * pinos_client_info_update (PinosClientInfo *info,
const PinosClientInfo *update);
void pinos_client_info_free (PinosClientInfo *info);
/**
* PinosClientInfoCallback:
* @c: a #PinosContext
* @info: a #PinosClientInfo
* @user_data: user data
*
* Callback with information about the Pinos client in @info.
*/
typedef void (*PinosClientInfoCallback) (PinosContext *c,
SpaResult res,
const PinosClientInfo *info,
void *user_data);
void pinos_context_list_client_info (PinosContext *context,
PinosClientInfoCallback cb,
void *user_data);
void pinos_context_get_client_info_by_id (PinosContext *context,
uint32_t id,
PinosClientInfoCallback cb,
void *user_data);
/**
* PinosNodeInfo:
* @id: generic id of the node
* @change_mask: bitfield of changed fields since last call
* @name: name the node, suitable for display
* @state: the current state of the node
* @error: an error reason if @state is error
* @props: the properties of the node
*
* The node information. Extra information can be added in later
* versions.
*/
struct _PinosNodeInfo {
uint32_t id;
uint64_t change_mask;
const char *name;
uint32_t max_inputs;
uint32_t n_inputs;
uint32_t n_input_formats;
SpaFormat **input_formats;
uint32_t max_outputs;
uint32_t n_outputs;
uint32_t n_output_formats;
SpaFormat **output_formats;
PinosNodeState state;
const char *error;
SpaDict *props;
};
PinosNodeInfo * pinos_node_info_update (PinosNodeInfo *info,
const PinosNodeInfo *update);
void pinos_node_info_free (PinosNodeInfo *info);
/**
* PinosNodeInfoCallback:
* @c: a #PinosContext
* @info: a #PinosNodeInfo
* @user_data: user data
*
* Callback with information about the Pinos node in @info.
*/
typedef void (*PinosNodeInfoCallback) (PinosContext *c,
SpaResult res,
const PinosNodeInfo *info,
void *user_data);
void pinos_context_list_node_info (PinosContext *context,
PinosNodeInfoCallback cb,
void *user_data);
void pinos_context_get_node_info_by_id (PinosContext *context,
uint32_t id,
PinosNodeInfoCallback cb,
void *user_data);
/**
* PinosLinkInfo:
* @id: generic id of the link
* @change_mask: bitfield of changed fields since last call
* @output_node_path: the output node
* @output_port: the output port
* @input_node_path: the input node
* @input_port: the input port
*
* The link information. Extra information can be added in later
* versions.
*/
struct _PinosLinkInfo {
uint32_t id;
uint64_t change_mask;
uint32_t output_node_id;
uint32_t output_port_id;
uint32_t input_node_id;
uint32_t input_port_id;
};
PinosLinkInfo * pinos_link_info_update (PinosLinkInfo *info,
const PinosLinkInfo *update);
void pinos_link_info_free (PinosLinkInfo *info);
/**
* PinosLinkInfoCallback:
* @c: a #PinosContext
* @info: a #PinosLinkInfo
* @user_data: user data
*
* Callback with information about the Pinos link in @info.
*/
typedef void (*PinosLinkInfoCallback) (PinosContext *c,
SpaResult res,
const PinosLinkInfo *info,
void *user_data);
void pinos_context_list_link_info (PinosContext *context,
PinosLinkInfoCallback cb,
void *user_data);
void pinos_context_get_link_info_by_id (PinosContext *context,
uint32_t id,
PinosLinkInfoCallback cb,
void *user_data);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_INTROSPECT_H__ */

View file

@ -1,90 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_LOG_H__
#define __PINOS_LOG_H__
#include <spa/log.h>
#include <spa/loop.h>
#ifdef __cplusplus
extern "C" {
#endif
extern SpaLogLevel pinos_log_level;
SpaLog * pinos_log_get (void);
void pinos_log_set_level (SpaLogLevel level);
void pinos_log_set_trace_event (SpaSource *source);
void pinos_log_log (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt, ...) SPA_PRINTF_FUNC(5, 6);
void pinos_log_logv (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt,
va_list args) SPA_PRINTF_FUNC(5, 0);
#define pinos_log_level_enabled(lev) (pinos_log_level >= (lev))
#if __STDC_VERSION__ >= 199901L
#define pinos_log_logc(lev,...) \
if (SPA_UNLIKELY (pinos_log_level_enabled (lev))) \
pinos_log_log(lev,__VA_ARGS__)
#define pinos_log_error(...) pinos_log_logc(SPA_LOG_LEVEL_ERROR,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pinos_log_warn(...) pinos_log_logc(SPA_LOG_LEVEL_WARN,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pinos_log_info(...) pinos_log_logc(SPA_LOG_LEVEL_INFO,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pinos_log_debug(...) pinos_log_logc(SPA_LOG_LEVEL_DEBUG,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pinos_log_trace(...) pinos_log_logc(SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__)
#else
#include <stdarg.h>
#define PINOS_LOG_FUNC(name,lev) \
static inline void pinos_log_##name (const char *format, ...) \
{ \
if (SPA_UNLIKELY (pinos_log_level_enabled (lev))) { \
va_list varargs; \
va_start (varargs, format); \
pinos_log_logv (lev,__FILE__,__LINE__,__func__,format,varargs); \
va_end (varargs); \
} \
}
PINOS_LOG_FUNC(error, SPA_LOG_LEVEL_ERROR)
PINOS_LOG_FUNC(warn, SPA_LOG_LEVEL_WARN)
PINOS_LOG_FUNC(info, SPA_LOG_LEVEL_INFO)
PINOS_LOG_FUNC(debug, SPA_LOG_LEVEL_DEBUG)
PINOS_LOG_FUNC(trace, SPA_LOG_LEVEL_TRACE)
#endif
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_LOG_H__ */

View file

@ -1,78 +0,0 @@
/* Pinos
* Copyright (C) 2016 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.
*/
#ifndef __PINOS_LOOP_H__
#define __PINOS_LOOP_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/list.h>
#include <spa/loop.h>
#include <pinos/client/sig.h>
typedef struct _PinosLoop PinosLoop;
/**
* PinosLoop:
*
* Pinos loop interface.
*/
struct _PinosLoop {
SpaLoop *loop;
SpaLoopControl *control;
SpaLoopUtils *utils;
PINOS_SIGNAL (before_iterate, (PinosListener *listener,
PinosLoop *loop));
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosLoop *loop));
};
PinosLoop * pinos_loop_new (void);
void pinos_loop_destroy (PinosLoop *loop);
#define pinos_loop_add_source(l,...) spa_loop_add_source((l)->loop,__VA_ARGS__)
#define pinos_loop_update_source(l,...) spa_loop_update_source(__VA_ARGS__)
#define pinos_loop_remove_source(l,...) spa_loop_remove_source(__VA_ARGS__)
#define pinos_loop_invoke(l,...) spa_loop_invoke((l)->loop,__VA_ARGS__)
#define pinos_loop_get_fd(l) spa_loop_control_get_fd((l)->control)
#define pinos_loop_set_hooks(l,...) spa_loop_control_set_hooks((l)->control,__VA_ARGS__)
#define pinos_loop_enter(l) spa_loop_control_enter((l)->control)
#define pinos_loop_iterate(l,...) spa_loop_control_iterate((l)->control,__VA_ARGS__)
#define pinos_loop_leave(l) spa_loop_control_leave((l)->control)
#define pinos_loop_add_io(l,...) spa_loop_utils_add_io((l)->utils,__VA_ARGS__)
#define pinos_loop_update_io(l,...) spa_loop_utils_update_io((l)->utils,__VA_ARGS__)
#define pinos_loop_add_idle(l,...) spa_loop_utils_add_idle((l)->utils,__VA_ARGS__)
#define pinos_loop_enable_idle(l,...) spa_loop_utils_enable_idle((l)->utils,__VA_ARGS__)
#define pinos_loop_add_event(l,...) spa_loop_utils_add_event((l)->utils,__VA_ARGS__)
#define pinos_loop_signal_event(l,...) spa_loop_utils_signal_event((l)->utils,__VA_ARGS__)
#define pinos_loop_add_timer(l,...) spa_loop_utils_add_timer((l)->utils,__VA_ARGS__)
#define pinos_loop_update_timer(l,...) spa_loop_utils_update_timer((l)->utils,__VA_ARGS__)
#define pinos_loop_add_signal(l,...) spa_loop_utils_add_signal((l)->utils,__VA_ARGS__)
#define pinos_loop_destroy_source(l,...) spa_loop_utils_destroy_source((l)->utils,__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_LOOP_H__ */

View file

@ -1,153 +0,0 @@
/* Pinos
* Copyright (C) 2016 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.
*/
#ifndef __PINOS_MAP_H__
#define __PINOS_MAP_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosMap PinosMap;
#include <string.h>
#include <stdio.h>
#include <spa/defs.h>
#include <pinos/client/array.h>
#include <pinos/client/log.h>
typedef union {
uint32_t next;
void *data;
} PinosMapItem;
struct _PinosMap {
PinosArray items;
uint32_t free_list;
};
#define PINOS_MAP_INIT(extend) { PINOS_ARRAY_INIT(extend), 0 }
#define pinos_map_get_size(m) pinos_array_get_len (&(m)->items, PinosMapItem)
#define pinos_map_get_item(m,id) pinos_array_get_unchecked(&(m)->items,id,PinosMapItem)
#define pinos_map_item_is_free(item) ((item)->next & 0x1)
#define pinos_map_id_is_free(m,id) (pinos_map_item_is_free (pinos_map_get_item(m,id)))
#define pinos_map_check_id(m,id) ((id) < pinos_map_get_size (m))
#define pinos_map_has_item(m,id) (pinos_map_check_id(m,id) && !pinos_map_id_is_free(m, id))
#define pinos_map_lookup_unchecked(m,id) pinos_map_get_item(m,id)->data
#define PINOS_MAP_ID_TO_PTR(id) (SPA_UINT32_TO_PTR((id)<<1))
#define PINOS_MAP_PTR_TO_ID(p) (SPA_PTR_TO_UINT32(p)>>1)
static inline void
pinos_map_init (PinosMap *map,
size_t size,
size_t extend)
{
pinos_array_init (&map->items, extend);
pinos_array_ensure_size (&map->items, size * sizeof (PinosMapItem));
map->free_list = 0;
}
static inline void
pinos_map_clear (PinosMap *map)
{
pinos_array_clear (&map->items);
}
static inline uint32_t
pinos_map_insert_new (PinosMap *map,
void *data)
{
PinosMapItem *start, *item;
uint32_t id;
if (map->free_list) {
start = map->items.data;
item = &start[map->free_list >> 1];
map->free_list = item->next;
} else {
item = pinos_array_add (&map->items, sizeof (PinosMapItem));
if (!item)
return SPA_ID_INVALID;
start = map->items.data;
}
item->data = data;
id = (item - start);
return id;
}
static inline bool
pinos_map_insert_at (PinosMap *map,
uint32_t id,
void *data)
{
size_t size = pinos_map_get_size (map);
PinosMapItem *item;
if (id > size)
return false;
else if (id == size)
item = pinos_array_add (&map->items, sizeof (PinosMapItem));
else
item = pinos_map_get_item (map, id);
item->data = data;
return true;
}
static inline void
pinos_map_remove (PinosMap *map,
uint32_t id)
{
pinos_map_get_item (map, id)->next = map->free_list;
map->free_list = (id << 1) | 1;
}
static inline void *
pinos_map_lookup (PinosMap *map,
uint32_t id)
{
if (SPA_LIKELY (pinos_map_check_id (map, id))) {
PinosMapItem *item = pinos_map_get_item (map, id);
if (!pinos_map_item_is_free (item))
return item->data;
}
return NULL;
}
static inline void
pinos_map_for_each (PinosMap *map,
void (*func) (void *, void *),
void *data)
{
PinosMapItem *item;
pinos_array_for_each (item, &map->items) {
if (item->data && !pinos_map_item_is_free (item))
func (item->data, data);
}
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __PINOS_MAP_H__ */

View file

@ -1,157 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <unistd.h>
#include <stdio.h>
#include <sys/prctl.h>
#include <pwd.h>
#include "pinos/client/pinos.h"
/**
* pinos_init:
* @argc: pointer to argc
* @argv: pointer to argv
*
* initialize the pinos system, parse and modify any parameters given
* by @argc and @argv.
*/
void
pinos_init (int *argc, char **argv[])
{
const char *str;
if ((str = getenv ("PINOS_DEBUG")))
pinos_log_set_level (atoi (str));
}
const char *
pinos_get_application_name (void)
{
return NULL;
}
const char *
pinos_get_prgname (void)
{
static char tcomm[16+1];
spa_zero(tcomm);
if (prctl (PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
return tcomm;
return NULL;
}
const char *
pinos_get_user_name (void)
{
struct passwd *pw;
if ((pw = getpwuid (getuid ())))
return pw->pw_name;
return NULL;
}
const char *
pinos_get_host_name (void)
{
static char hname[256];
if (gethostname (hname, 256) < 0)
return NULL;
hname[255] = 0;
return hname;
}
/**
* pinos_client_name:
*
* Make a new pinos client name that can be used to construct a context.
*/
char *
pinos_client_name (void)
{
char *c;
const char *cc;
if ((cc = pinos_get_application_name ()))
return strdup (cc);
else if ((cc = pinos_get_prgname ()))
return strdup (cc);
else {
asprintf (&c, "pinos-pid-%zd", (size_t) getpid ());
return c;
}
}
/**
* pinos_fill_context_properties:
* @properties: a #PinosProperties
*
* Fill @properties with a set of default context properties.
*/
void
pinos_fill_context_properties (PinosProperties *properties)
{
if (!pinos_properties_get (properties, "application.name"))
pinos_properties_set (properties, "application.name", pinos_get_application_name ());
if (!pinos_properties_get (properties, "application.prgname"))
pinos_properties_set (properties, "application.prgname", pinos_get_prgname ());
if (!pinos_properties_get (properties, "application.language")) {
pinos_properties_set (properties, "application.language", getenv ("LANG"));
}
if (!pinos_properties_get (properties, "application.process.id")) {
pinos_properties_setf (properties, "application.process.id", "%zd", (size_t) getpid ());
}
if (!pinos_properties_get (properties, "application.process.user"))
pinos_properties_set (properties, "application.process.user", pinos_get_user_name ());
if (!pinos_properties_get (properties, "application.process.host"))
pinos_properties_set (properties, "application.process.host", pinos_get_host_name ());
if (!pinos_properties_get (properties, "application.process.session_id")) {
pinos_properties_set (properties, "application.process.session_id", getenv ("XDG_SESSION_ID"));
}
}
/**
* pinos_fill_stream_properties
* @properties: a #PinosProperties
*
* Fill @properties with a set of default stream properties.
*/
void
pinos_fill_stream_properties (PinosProperties *properties)
{
}
PinosDirection
pinos_direction_reverse (PinosDirection direction)
{
if (direction == PINOS_DIRECTION_INPUT)
return PINOS_DIRECTION_OUTPUT;
else if (direction == PINOS_DIRECTION_OUTPUT)
return PINOS_DIRECTION_INPUT;
return direction;
}

View file

@ -1,60 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_H__
#define __PINOS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <pinos/client/context.h>
#include <pinos/client/introspect.h>
#include <pinos/client/log.h>
#include <pinos/client/loop.h>
#include <pinos/client/mem.h>
#include <pinos/client/thread-mainloop.h>
#include <pinos/client/properties.h>
#include <pinos/client/stream.h>
#include <pinos/client/subscribe.h>
#include <pinos/client/utils.h>
#include <spa/type-map.h>
void pinos_init (int *argc, char **argv[]);
const char * pinos_get_application_name (void);
const char * pinos_get_prgname (void);
const char * pinos_get_user_name (void);
const char * pinos_get_host_name (void);
char * pinos_client_name (void);
void pinos_fill_context_properties (PinosProperties *properties);
void pinos_fill_stream_properties (PinosProperties *properties);
PinosDirection pinos_direction_reverse (PinosDirection direction);
SpaTypeMap * pinos_type_map_get_default (void);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_H__ */

View file

@ -1,59 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_PROPERTIES_H__
#define __PINOS_PROPERTIES_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosProperties PinosProperties;
#include <spa/dict.h>
struct _PinosProperties {
SpaDict dict;
};
PinosProperties * pinos_properties_new (const char *key, ...);
PinosProperties * pinos_properties_new_dict (const SpaDict *dict);
PinosProperties * pinos_properties_copy (PinosProperties *properties);
PinosProperties * pinos_properties_merge (PinosProperties *oldprops,
PinosProperties *newprops);
void pinos_properties_free (PinosProperties *properties);
void pinos_properties_set (PinosProperties *properties,
const char *key,
const char *value);
void pinos_properties_setf (PinosProperties *properties,
const char *key,
const char *format,
...) SPA_PRINTF_FUNC (3, 4);
const char * pinos_properties_get (PinosProperties *properties,
const char *key);
const char * pinos_properties_iterate (PinosProperties *properties,
void **state);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_PROPERTIES_H__ */

View file

@ -1,133 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_STREAM_H__
#define __PINOS_STREAM_H__
#include <spa/buffer.h>
#include <spa/format.h>
#include <pinos/client/context.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosStream PinosStream;
typedef enum {
PINOS_STREAM_STATE_ERROR = -1,
PINOS_STREAM_STATE_UNCONNECTED = 0,
PINOS_STREAM_STATE_CONNECTING = 1,
PINOS_STREAM_STATE_CONFIGURE = 2,
PINOS_STREAM_STATE_READY = 3,
PINOS_STREAM_STATE_PAUSED = 4,
PINOS_STREAM_STATE_STREAMING = 5
} PinosStreamState;
const char * pinos_stream_state_as_string (PinosStreamState state);
typedef enum {
PINOS_STREAM_FLAG_NONE = 0,
PINOS_STREAM_FLAG_AUTOCONNECT = (1 << 0),
PINOS_STREAM_FLAG_CLOCK_UPDATE = (1 << 1),
} PinosStreamFlags;
typedef enum {
PINOS_STREAM_MODE_BUFFER = 0,
PINOS_STREAM_MODE_RINGBUFFER = 1,
} PinosStreamMode;
typedef struct {
int64_t now;
int64_t ticks;
int32_t rate;
} PinosTime;
/**
* PinosStream:
*
* Pinos stream object class.
*/
struct _PinosStream {
PinosContext *context;
SpaList link;
char *name;
PinosProperties *properties;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosStream *stream));
PinosStreamState state;
char *error;
PINOS_SIGNAL (state_changed, (PinosListener *listener,
PinosStream *stream));
PINOS_SIGNAL (format_changed, (PinosListener *listener,
PinosStream *stream,
SpaFormat *format));
PINOS_SIGNAL (add_buffer, (PinosListener *listener,
PinosStream *stream,
uint32_t id));
PINOS_SIGNAL (remove_buffer, (PinosListener *listener,
PinosStream *stream,
uint32_t id));
PINOS_SIGNAL (new_buffer, (PinosListener *listener,
PinosStream *stream,
uint32_t id));
PINOS_SIGNAL (need_buffer, (PinosListener *listener,
PinosStream *stream));
};
PinosStream * pinos_stream_new (PinosContext *context,
const char *name,
PinosProperties *props);
void pinos_stream_destroy (PinosStream *stream);
bool pinos_stream_connect (PinosStream *stream,
PinosDirection direction,
PinosStreamMode mode,
const char *port_path,
PinosStreamFlags flags,
uint32_t n_possible_formats,
SpaFormat **possible_formats);
bool pinos_stream_disconnect (PinosStream *stream);
bool pinos_stream_finish_format (PinosStream *stream,
SpaResult res,
SpaParam **params,
uint32_t n_params);
bool pinos_stream_get_time (PinosStream *stream,
PinosTime *time);
uint32_t pinos_stream_get_empty_buffer (PinosStream *stream);
bool pinos_stream_recycle_buffer (PinosStream *stream,
uint32_t id);
SpaBuffer * pinos_stream_peek_buffer (PinosStream *stream,
uint32_t id);
bool pinos_stream_send_buffer (PinosStream *stream,
uint32_t id);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_STREAM_H__ */

View file

@ -1,57 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_SUBSCRIBE_H__
#define __PINOS_SUBSCRIBE_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PINOS_TYPE__Core "Pinos:Object:Core"
#define PINOS_TYPE_CORE_BASE PINOS_TYPE__Core ":"
#define PINOS_TYPE__Registry "Pinos:Object:Registry"
#define PINOS_TYPE_REGISYRY_BASE PINOS_TYPE__Registry ":"
#define PINOS_TYPE__Node "Pinos:Object:Node"
#define PINOS_TYPE_NODE_BASE PINOS_TYPE__Node ":"
#define PINOS_TYPE__Client "Pinos:Object:Client"
#define PINOS_TYPE_CLIENT_BASE PINOS_TYPE__Client ":"
#define PINOS_TYPE__Link "Pinos:Object:Link"
#define PINOS_TYPE_LINK_BASE PINOS_TYPE__Link ":"
#define PINOS_TYPE__Module "Pinos:Object:Module"
#define PINOS_TYPE_MODULE_BASE PINOS_TYPE__Module ":"
typedef enum {
PINOS_SUBSCRIPTION_EVENT_NEW = 0,
PINOS_SUBSCRIPTION_EVENT_CHANGE = 1,
PINOS_SUBSCRIPTION_EVENT_REMOVE = 2,
} PinosSubscriptionEvent;
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_SUBSCRIBE_H__ */

View file

@ -1,65 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_THREAD_MAIN_LOOP_H__
#define __PINOS_THREAD_MAIN_LOOP_H__
#include <pinos/client/loop.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosThreadMainLoop PinosThreadMainLoop;
/**
* PinosThreadMainLoop:
*
* Pinos main loop object class.
*/
struct _PinosThreadMainLoop {
PinosLoop *loop;
char *name;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosThreadMainLoop *loop));
};
PinosThreadMainLoop * pinos_thread_main_loop_new (PinosLoop *loop,
const char *name);
void pinos_thread_main_loop_destroy (PinosThreadMainLoop *loop);
SpaResult pinos_thread_main_loop_start (PinosThreadMainLoop *loop);
void pinos_thread_main_loop_stop (PinosThreadMainLoop *loop);
void pinos_thread_main_loop_lock (PinosThreadMainLoop *loop);
void pinos_thread_main_loop_unlock (PinosThreadMainLoop *loop);
void pinos_thread_main_loop_wait (PinosThreadMainLoop *loop);
void pinos_thread_main_loop_signal (PinosThreadMainLoop *loop,
bool wait_for_accept);
void pinos_thread_main_loop_accept (PinosThreadMainLoop *loop);
bool pinos_thread_main_loop_in_thread (PinosThreadMainLoop *loop);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_THREAD_MAIN_LOOP_H__ */

View file

@ -1,131 +0,0 @@
/* Pinos
* Copyright (C) 2016 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.
*/
#ifndef __PINOS_TRANSPORT_H__
#define __PINOS_TRANSPORT_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosTransport PinosTransport;
typedef struct _PinosTransportArea PinosTransportArea;
#include <string.h>
#include <spa/defs.h>
#include <spa/node.h>
#include <pinos/client/mem.h>
#include <pinos/client/sig.h>
typedef struct {
int memfd;
uint32_t offset;
uint32_t size;
} PinosTransportInfo;
/**
* PinosTransportArea:
*
* Shared structure between client and server
*/
struct _PinosTransportArea {
uint32_t max_inputs;
uint32_t n_inputs;
uint32_t max_outputs;
uint32_t n_outputs;
};
struct _PinosTransport {
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosTransport *trans));
PinosTransportArea *area;
SpaPortIO *inputs;
SpaPortIO *outputs;
void *input_data;
SpaRingbuffer *input_buffer;
void *output_data;
SpaRingbuffer *output_buffer;
};
PinosTransport * pinos_transport_new (uint32_t max_inputs,
uint32_t max_outputs);
PinosTransport * pinos_transport_new_from_info (PinosTransportInfo *info);
void pinos_transport_destroy (PinosTransport *trans);
SpaResult pinos_transport_get_info (PinosTransport *trans,
PinosTransportInfo *info);
SpaResult pinos_transport_add_event (PinosTransport *trans,
SpaEvent *event);
SpaResult pinos_transport_next_event (PinosTransport *trans,
SpaEvent *event);
SpaResult pinos_transport_parse_event (PinosTransport *trans,
void *event);
#define PINOS_TYPE_EVENT__Transport SPA_TYPE_EVENT_BASE "Transport"
#define PINOS_TYPE_EVENT_TRANSPORT_BASE PINOS_TYPE_EVENT__Transport ":"
#define PINOS_TYPE_EVENT_TRANSPORT__HaveOutput PINOS_TYPE_EVENT_TRANSPORT_BASE "HaveOutput"
#define PINOS_TYPE_EVENT_TRANSPORT__NeedInput PINOS_TYPE_EVENT_TRANSPORT_BASE "NeedInput"
#define PINOS_TYPE_EVENT_TRANSPORT__ReuseBuffer PINOS_TYPE_EVENT_TRANSPORT_BASE "ReuseBuffer"
typedef struct {
uint32_t HaveOutput;
uint32_t NeedInput;
uint32_t ReuseBuffer;
} PinosTypeEventTransport;
static inline void
pinos_type_event_transport_map (SpaTypeMap *map, PinosTypeEventTransport *type)
{
if (type->HaveOutput == 0) {
type->HaveOutput = spa_type_map_get_id (map, PINOS_TYPE_EVENT_TRANSPORT__HaveOutput);
type->NeedInput = spa_type_map_get_id (map, PINOS_TYPE_EVENT_TRANSPORT__NeedInput);
type->ReuseBuffer = spa_type_map_get_id (map, PINOS_TYPE_EVENT_TRANSPORT__ReuseBuffer);
}
}
typedef struct {
SpaPODObjectBody body;
SpaPODInt port_id;
SpaPODInt buffer_id;
} PinosEventTransportReuseBufferBody;
typedef struct {
SpaPOD pod;
PinosEventTransportReuseBufferBody body;
} PinosEventTransportReuseBuffer;
#define PINOS_EVENT_TRANSPORT_REUSE_BUFFER_INIT(type,port_id,buffer_id) \
SPA_EVENT_INIT_COMPLEX (PinosEventTransportReuseBuffer, \
sizeof (PinosEventTransportReuseBufferBody), type, \
SPA_POD_INT_INIT (port_id), \
SPA_POD_INT_INIT (buffer_id))
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __PINOS_TRANSPORT_H__ */

View file

@ -1 +0,0 @@
pinos.desktop

View file

@ -1,50 +0,0 @@
/* Pinos
* Copyright (C) 2016 Axis Communications <dev-gstreamer@axis.com>
* @author Linus Svensson <linus.svensson@axis.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.
*/
#ifndef __PINOS_DAEMON_CONFIG_H__
#define __PINOS_DAEMON_CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <pinos/server/core.h>
typedef struct _PinosDaemonConfig PinosDaemonConfig;
struct _PinosDaemonConfig {
SpaList commands;
};
PinosDaemonConfig * pinos_daemon_config_new (void);
void pinos_daemon_config_free (PinosDaemonConfig *config);
bool pinos_daemon_config_load_file (PinosDaemonConfig *config,
const char *filename,
char **err);
bool pinos_daemon_config_load (PinosDaemonConfig *config,
char **err);
bool pinos_daemon_config_run_commands (PinosDaemonConfig *config,
PinosCore *core);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_DAEMON_CONFIG_H__ */

View file

@ -1,30 +0,0 @@
pinos_sources = [
'main.c',
'daemon-config.c',
]
pinos_headers = [
'daemon-config.h',
]
pinos_c_args = [
'-DHAVE_CONFIG_H',
'-D_GNU_SOURCE',
'-DG_LOG_DOMAIN=g_log_domain_pinos',
]
conf_config = configuration_data()
conf_install_dir = '@0@/pinos'.format(get_option('sysconfdir'))
configure_file(input : 'pinos.conf.in',
output : 'pinos.conf',
configuration : conf_config,
install_dir : conf_install_dir)
executable('pinos',
pinos_sources,
install: true,
c_args : pinos_c_args,
include_directories : [configinc, spa_inc],
dependencies : [pinos_dep, pinoscore_dep],
)

View file

@ -1,7 +0,0 @@
#load-module libpinos-module-protocol-dbus
load-module libpinos-module-protocol-native
load-module libpinos-module-suspend-on-idle
load-module libpinos-module-spa --pattern snow
load-module libpinos-module-autolink
#load-module libpinos-module-mixer
load-module libpinos-module-flatpak

View file

@ -1,2 +0,0 @@
org-pinos.c
org-pinos.h

View file

@ -1,15 +0,0 @@
gdbus_codegen = find_program('gdbus-codegen')
org_pinos_files = ['org-pinos.c', 'org-pinos.h']
gdbus_target = custom_target('org-pinos',
output : org_pinos_files,
input : 'org.pinos.xml',
command : [gdbus_codegen,
'--interface-prefix', 'org.pinos.',
'--generate-c-code', 'pinos/dbus/org-pinos',
'--c-namespace', 'Pinos',
'--c-generate-object-manager',
'@INPUT@'],
)

View file

@ -1,131 +0,0 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" >
<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<!--
org.pinos.Daemon1:
@short_description: Main interface for the pinos daemon
Interface to get properties from the pinos daemon and to
establish a client connection.
-->
<interface name='org.pinos.Daemon1'>
<!-- UserName: Name of the user that started the daemon -->
<property name='UserName' type='s' access='read' />
<!-- HostName: Name of the machine the daemon is running on -->
<property name='HostName' type='s' access='read' />
<!-- Version: Version of the daemon -->
<property name='Version' type='s' access='read' />
<!-- Name: Name of the daemon -->
<property name='Name' type='s' access='read' />
<!-- Cookie: A random cookie for identifying this instance of Pinos -->
<property name='Cookie' type='u' access='read' />
<!-- Properties: Extra properties of the daemon -->
<property name='Properties' type='a{sv}' access='read' />
<!-- CreateNode:
@factory_name: the factory name to use for the node
@name: the name of the node
@Properties: extra properties
@node: the Node1 object path
Create a new Node with given name and properties
-->
<method name='CreateNode'>
<arg type='s' name='factory_name' direction='in' />
<arg type='s' name='name' direction='in' />
<arg type='a{sv}' name='properties' direction='in'/>
<arg type='o' name='node' direction='out'/>
</method>
<!-- CreateClientNode:
@name: the name of the node
@Properties: extra properties
@node: the Node1 object path
Create a new Node
-->
<method name='CreateClientNode'>
<arg type='s' name='name' direction='in' />
<arg type='a{sv}' name='properties' direction='in'/>
<arg type='o' name='node' direction='out'/>
<arg type='h' name='fd' direction='out'/>
<arg type='h' name='rtfd' direction='out'/>
</method>
</interface>
<interface name='org.pinos.Client1'>
<!-- Sender: Sender of the client -->
<property name='Sender' type='s' access='read' />
<!-- Name: Properties of the client -->
<property name='Properties' type='a{sv}' access='read' />
</interface>
<!--
org.pinos.Node1:
@short_description: A processing node
A node is an object that can consume and/or produce media.
-->
<interface name='org.pinos.Node1'>
<!-- Name: the name of the node -->
<property name='Name' type='s' access='read' />
<!-- Owner: the owner path of this node -->
<property name='Owner' type='s' access='read' />
<!-- Properties: extra node properties -->
<property name='Properties' type='a{sv}' access='read' />
<property name='Ports' type='a(uu)' access='read' />
<method name='Link'>
<arg type='o' name='input_node' direction='in' />
<arg type='s' name='format_filter' direction='in'/>
<arg type='a{sv}' name='properties' direction='in'/>
<arg type='o' name='link' direction='out' />
</method>
<!-- state: state of the node
-1 = the node is in error
0 = the node is suspended, this means that the node is not
processing any data and has closed all devices if any
1 = the node is initializing
2 = the node is idle, this means no channel is consuming
the data. An idle node can become suspended.
3 = the node is running
-->
<property name='State' type='u' access='read' />
<!-- Activate:
Set the node ready for processing
-->
<method name='Activate'>
</method>
<method name='Deactivate'>
</method>
<!-- Remove:
Remove the node
-->
<method name='Remove'/>
</interface>
<interface name='org.pinos.Link1'>
<!-- Owner: the owner path of this link -->
<property name='Owner' type='s' access='read' />
<property name='OutputNode' type='o' access='read' />
<property name='OutputPort' type='u' access='read' />
<property name='InputNode' type='o' access='read' />
<property name='InputPort' type='u' access='read' />
<property name='Properties' type='a{sv}' access='read' />
<property name='Format' type='s' access='read' />
<method name='Remove'/>
</interface>
</node>

View file

@ -1,62 +0,0 @@
/* GStreamer
* Copyright (C) <2016> 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.
*/
#ifndef __GST_PINOS_CLOCK_H__
#define __GST_PINOS_CLOCK_H__
#include <gst/gst.h>
#include <pinos/client/pinos.h>
G_BEGIN_DECLS
#define GST_TYPE_PINOS_CLOCK \
(gst_pinos_clock_get_type())
#define GST_PINOS_CLOCK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PINOS_CLOCK,GstPinosClock))
#define GST_PINOS_CLOCK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PINOS_CLOCK,GstPinosClockClass))
#define GST_IS_PINOS_CLOCK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PINOS_CLOCK))
#define GST_IS_PINOS_CLOCK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PINOS_CLOCK))
#define GST_PINOS_CLOCK_GET_CLASS(klass) \
(G_TYPE_INSTANCE_GET_CLASS ((klass), GST_TYPE_PINOS_CLOCK, GstPinosClockClass))
typedef struct _GstPinosClock GstPinosClock;
typedef struct _GstPinosClockClass GstPinosClockClass;
struct _GstPinosClock {
GstSystemClock parent;
PinosStream *stream;
};
struct _GstPinosClockClass {
GstSystemClockClass parent_class;
};
GType gst_pinos_clock_get_type (void);
GstClock * gst_pinos_clock_new (PinosStream *stream);
G_END_DECLS
#endif /* __GST_PINOS_CLOCK_H__ */

View file

@ -1,100 +0,0 @@
/* GStreamer
* Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
* (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* pinosdeviceprovider.h: Device probing and monitoring
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_PINOS_DEVICE_PROVIDER_H__
#define __GST_PINOS_DEVICE_PROVIDER_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <pinos/client/pinos.h>
#include <gst/gst.h>
G_BEGIN_DECLS
typedef struct _GstPinosDevice GstPinosDevice;
typedef struct _GstPinosDeviceClass GstPinosDeviceClass;
#define GST_TYPE_PINOS_DEVICE (gst_pinos_device_get_type())
#define GST_IS_PINOS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PINOS_DEVICE))
#define GST_IS_PINOS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PINOS_DEVICE))
#define GST_PINOS_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PINOS_DEVICE, GstPinosDeviceClass))
#define GST_PINOS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PINOS_DEVICE, GstPinosDevice))
#define GST_PINOS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE, GstPinosDeviceClass))
#define GST_PINOS_DEVICE_CAST(obj) ((GstPinosDevice *)(obj))
typedef enum {
GST_PINOS_DEVICE_TYPE_UNKNOWN,
GST_PINOS_DEVICE_TYPE_SOURCE,
GST_PINOS_DEVICE_TYPE_SINK,
} GstPinosDeviceType;
struct _GstPinosDevice {
GstDevice parent;
GstPinosDeviceType type;
uint32_t id;
const gchar *element;
};
struct _GstPinosDeviceClass {
GstDeviceClass parent_class;
};
GType gst_pinos_device_get_type (void);
typedef struct _GstPinosDeviceProvider GstPinosDeviceProvider;
typedef struct _GstPinosDeviceProviderClass GstPinosDeviceProviderClass;
#define GST_TYPE_PINOS_DEVICE_PROVIDER (gst_pinos_device_provider_get_type())
#define GST_IS_PINOS_DEVICE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PINOS_DEVICE_PROVIDER))
#define GST_IS_PINOS_DEVICE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PINOS_DEVICE_PROVIDER))
#define GST_PINOS_DEVICE_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PINOS_DEVICE_PROVIDER, GstPinosDeviceProviderClass))
#define GST_PINOS_DEVICE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PINOS_DEVICE_PROVIDER, GstPinosDeviceProvider))
#define GST_PINOS_DEVICE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE_PROVIDER, GstPinosDeviceProviderClass))
#define GST_PINOS_DEVICE_PROVIDER_CAST(obj) ((GstPinosDeviceProvider *)(obj))
struct _GstPinosDeviceProvider {
GstDeviceProvider parent;
gchar *client_name;
PinosLoop *loop;
PinosThreadMainLoop *main_loop;
PinosContext *context;
PinosListener ctx_state_changed;
PinosListener ctx_subscription;
};
struct _GstPinosDeviceProviderClass {
GstDeviceProviderClass parent_class;
};
GType gst_pinos_device_provider_get_type (void);
G_END_DECLS
#endif /* __GST_PINOS_DEVICE_PROVIDER_H__ */

View file

@ -1,66 +0,0 @@
/* GStreamer
* Copyright (C) <2016> 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.
*/
#ifndef __GST_PINOS_POOL_H__
#define __GST_PINOS_POOL_H__
#include <gst/gst.h>
#include <pinos/client/pinos.h>
G_BEGIN_DECLS
#define GST_TYPE_PINOS_POOL \
(gst_pinos_pool_get_type())
#define GST_PINOS_POOL(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PINOS_POOL,GstPinosPool))
#define GST_PINOS_POOL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PINOS_POOL,GstPinosPoolClass))
#define GST_IS_PINOS_POOL(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PINOS_POOL))
#define GST_IS_PINOS_POOL_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PINOS_POOL))
#define GST_PINOS_POOL_GET_CLASS(klass) \
(G_TYPE_INSTANCE_GET_CLASS ((klass), GST_TYPE_PINOS_POOL, GstPinosPoolClass))
typedef struct _GstPinosPool GstPinosPool;
typedef struct _GstPinosPoolClass GstPinosPoolClass;
struct _GstPinosPool {
GstBufferPool parent;
PinosStream *stream;
GQueue available;
GCond cond;
};
struct _GstPinosPoolClass {
GstBufferPoolClass parent_class;
};
GType gst_pinos_pool_get_type (void);
GstPinosPool * gst_pinos_pool_new (void);
gboolean gst_pinos_pool_add_buffer (GstPinosPool *pool, GstBuffer *buffer);
gboolean gst_pinos_pool_remove_buffer (GstPinosPool *pool, GstBuffer *buffer);
G_END_DECLS
#endif /* __GST_PINOS_POOL_H__ */

View file

@ -1,113 +0,0 @@
/* GStreamer
* Copyright (C) <2015> 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.
*/
#ifndef __GST_PINOS_SINK_H__
#define __GST_PINOS_SINK_H__
#include <gst/gst.h>
#include <gst/base/gstbasesink.h>
#include <pinos/client/pinos.h>
#include <pinos/gst/gstpinospool.h>
G_BEGIN_DECLS
#define GST_TYPE_PINOS_SINK \
(gst_pinos_sink_get_type())
#define GST_PINOS_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PINOS_SINK,GstPinosSink))
#define GST_PINOS_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PINOS_SINK,GstPinosSinkClass))
#define GST_IS_PINOS_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PINOS_SINK))
#define GST_IS_PINOS_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PINOS_SINK))
#define GST_PINOS_SINK_CAST(obj) \
((GstPinosSink *) (obj))
typedef struct _GstPinosSink GstPinosSink;
typedef struct _GstPinosSinkClass GstPinosSinkClass;
/**
* GstPinosSinkMode:
* @GST_PINOS_SINK_MODE_DEFAULT: the default mode as configured in the server
* @GST_PINOS_SINK_MODE_RENDER: try to render the media
* @GST_PINOS_SINK_MODE_PROVIDE: provide the media
*
* Different modes of operation.
*/
typedef enum
{
GST_PINOS_SINK_MODE_DEFAULT,
GST_PINOS_SINK_MODE_RENDER,
GST_PINOS_SINK_MODE_PROVIDE,
} GstPinosSinkMode;
#define GST_TYPE_PINOS_SINK_MODE (gst_pinos_sink_mode_get_type ())
/**
* GstPinosSink:
*
* Opaque data structure.
*/
struct _GstPinosSink {
GstBaseSink element;
/*< private >*/
gchar *path;
gchar *client_name;
/* video state */
gboolean negotiated;
PinosLoop *loop;
PinosThreadMainLoop *main_loop;
PinosContext *ctx;
PinosListener ctx_state_changed;
PinosStream *stream;
PinosListener stream_state_changed;
PinosListener stream_format_changed;
PinosListener stream_add_buffer;
PinosListener stream_remove_buffer;
PinosListener stream_new_buffer;
PinosListener stream_need_buffer;
GstAllocator *allocator;
GstStructure *properties;
GstPinosSinkMode mode;
GstPinosPool *pool;
GHashTable *buf_ids;
GQueue queue;
guint need_ready;
};
struct _GstPinosSinkClass {
GstBaseSinkClass parent_class;
};
GType gst_pinos_sink_get_type (void);
GType gst_pinos_sink_mode_get_type (void);
G_END_DECLS
#endif /* __GST_PINOS_SINK_H__ */

View file

@ -1,31 +0,0 @@
pinos_gst_sources = [
'gstpinos.c',
'gstpinosclock.c',
'gstpinosdeviceprovider.c',
'gstpinosformat.c',
'gstpinospool.c',
'gstpinossink.c',
'gstpinossrc.c',
]
pinos_gst_headers = [
'gstpinosclock.h',
'gstpinosdeviceprovider.h',
'gstpinosformat.h',
'gstpinospool.h',
'gstpinossink.h',
'gstpinossrc.h',
]
pinos_gst_c_args = [
'-DHAVE_CONFIG_H',
]
pinos_gst = shared_library('gstpinos',
pinos_gst_sources,
c_args : pinos_gst_c_args,
include_directories : [configinc, spa_inc],
dependencies : [gobject_dep, glib_dep, gio_dep, gst_dep, pinos_dep, pinoscore_dep],
install : true,
install_dir : '@0@/gstreamer-1.0'.format(get_option('libdir')),
)

View file

@ -1,334 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <string.h>
#include <gst/gst.h>
#include <gio/gio.h>
#include "gst-manager.h"
#include "gst-source.h"
#include "gst-sink.h"
#define PINOS_GST_MANAGER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_GST_MANAGER, PinosGstManagerPrivate))
struct _PinosGstManagerPrivate
{
PinosDaemon *daemon;
GstDeviceMonitor *monitor;
};
enum
{
PROP_0,
PROP_DAEMON
};
G_DEFINE_TYPE (PinosGstManager, pinos_gst_manager, G_TYPE_OBJECT);
static gboolean
copy_properties (GQuark field_id,
const GValue *value,
gpointer user_data)
{
PinosProperties *properties = user_data;
if (G_VALUE_HOLDS_STRING (value))
pinos_properties_set (properties,
g_quark_to_string (field_id),
g_value_get_string (value));
return TRUE;
}
static void
device_added (PinosGstManager *manager,
GstDevice *device)
{
PinosGstManagerPrivate *priv = manager->priv;
gchar *name, *klass;
GstElement *element;
PinosNode *node = NULL;
GstStructure *p;
PinosProperties *properties;
GstCaps *caps;
name = gst_device_get_display_name (device);
if (g_strcmp0 (name, "gst") == 0) {
g_free (name);
return;
}
caps = gst_device_get_caps (device);
g_print("Device added: %s\n", name);
properties = pinos_properties_new (NULL, NULL);
if ((p = gst_device_get_properties (device))) {
gst_structure_foreach (p, copy_properties, properties);
gst_structure_free (p);
}
klass = gst_device_get_device_class (device);
pinos_properties_set (properties,
"gstreamer.device.class",
klass);
element = gst_device_create_element (device, NULL);
if (strstr (klass, "Source")) {
node = pinos_gst_source_new (priv->daemon,
name,
properties,
element,
caps,
NULL,
NULL);
} else if (strstr (klass, "Sink")) {
node = pinos_gst_sink_new (priv->daemon,
name,
properties,
element,
caps,
NULL,
NULL);
}
if (node)
g_object_set_data (G_OBJECT (device), "PinosNode", node);
pinos_properties_free (properties);
gst_caps_unref (caps);
g_free (name);
g_free (klass);
}
static void
device_removed (PinosGstManager *manager,
GstDevice *device)
{
gchar *name;
PinosNode *node;
name = gst_device_get_display_name (device);
if (strcmp (name, "gst") == 0)
return;
g_print("Device removed: %s\n", name);
node = g_object_steal_data (G_OBJECT (device), "PinosNode");
g_object_unref (node);
g_free (name);
}
static gboolean
bus_handler (GstBus *bus,
GstMessage *message,
gpointer user_data)
{
PinosGstManager *manager = user_data;
GstDevice *device;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_DEVICE_ADDED:
gst_message_parse_device_added (message, &device);
device_added (manager, device);
break;
case GST_MESSAGE_DEVICE_REMOVED:
gst_message_parse_device_removed (message, &device);
device_removed (manager, device);
break;
default:
break;
}
return TRUE;
}
static void
disable_pinos_provider (PinosGstManager *manager)
{
GList *factories = NULL;
factories = gst_device_provider_factory_list_get_device_providers (1);
while (factories) {
GstDeviceProviderFactory *factory = factories->data;
if (strcmp (GST_OBJECT_NAME (factory), "pinosdeviceprovider") == 0) {
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), 0);
}
factories = g_list_remove (factories, factory);
gst_object_unref (factory);
}
}
static void
start_monitor (PinosGstManager *manager)
{
PinosGstManagerPrivate *priv = manager->priv;
GstBus *bus;
GList *devices;
gchar **providers;
PinosProperties *props;
disable_pinos_provider (manager);
priv->monitor = gst_device_monitor_new ();
bus = gst_device_monitor_get_bus (priv->monitor);
gst_bus_add_watch (bus, bus_handler, manager);
gst_object_unref (bus);
gst_device_monitor_add_filter (priv->monitor, "Video/Source", NULL);
gst_device_monitor_add_filter (priv->monitor, "Audio/Source", NULL);
gst_device_monitor_add_filter (priv->monitor, "Audio/Sink", NULL);
gst_device_monitor_start (priv->monitor);
providers = gst_device_monitor_get_providers (priv->monitor);
if (providers != NULL) {
gchar *provided;
provided = g_strjoinv (",", providers);
g_strfreev (providers);
g_object_get (priv->daemon, "properties", &props, NULL);
pinos_properties_set (props, "gstreamer.deviceproviders", provided);
g_object_set (priv->daemon, "properties", props, NULL);
pinos_properties_free (props);
g_free (provided);
}
devices = gst_device_monitor_get_devices (priv->monitor);
while (devices != NULL) {
GstDevice *device = devices->data;
device_added (manager, device);
gst_object_unref (device);
devices = g_list_delete_link (devices, devices);
}
}
static void
stop_monitor (PinosGstManager *manager)
{
PinosGstManagerPrivate *priv = manager->priv;
if (priv->monitor) {
gst_device_monitor_stop (priv->monitor);
g_object_unref (priv->monitor);
priv->monitor = NULL;
}
}
static void
pinos_gst_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
PinosGstManager *manager = PINOS_GST_MANAGER (object);
PinosGstManagerPrivate *priv = manager->priv;
switch (prop_id) {
case PROP_DAEMON:
g_value_set_object (value, priv->daemon);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
pinos_gst_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
PinosGstManager *manager = PINOS_GST_MANAGER (object);
PinosGstManagerPrivate *priv = manager->priv;
switch (prop_id) {
case PROP_DAEMON:
priv->daemon = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_manager_constructed (GObject * object)
{
PinosGstManager *manager = PINOS_GST_MANAGER (object);
start_monitor (manager);
G_OBJECT_CLASS (pinos_gst_manager_parent_class)->constructed (object);
}
static void
gst_manager_finalize (GObject * object)
{
PinosGstManager *manager = PINOS_GST_MANAGER (object);
stop_monitor (manager);
G_OBJECT_CLASS (pinos_gst_manager_parent_class)->finalize (object);
}
static void
pinos_gst_manager_class_init (PinosGstManagerClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (PinosGstManagerPrivate));
gobject_class->constructed = gst_manager_constructed;
gobject_class->finalize = gst_manager_finalize;
gobject_class->set_property = pinos_gst_manager_set_property;
gobject_class->get_property = pinos_gst_manager_get_property;
g_object_class_install_property (gobject_class,
PROP_DAEMON,
g_param_spec_object ("daemon",
"Daemon",
"The daemon",
PINOS_TYPE_DAEMON,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}
static void
pinos_gst_manager_init (PinosGstManager * manager)
{
manager->priv = PINOS_GST_MANAGER_GET_PRIVATE (manager);
}
PinosGstManager *
pinos_gst_manager_new (PinosDaemon *daemon)
{
return g_object_new (PINOS_TYPE_GST_MANAGER, "daemon", daemon, NULL);
}

View file

@ -1,59 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_GST_MANAGER_H__
#define __PINOS_GST_MANAGER_H__
#include <glib-object.h>
#include <client/pinos.h>
#include <server/daemon.h>
G_BEGIN_DECLS
#define PINOS_TYPE_GST_MANAGER (pinos_gst_manager_get_type ())
#define PINOS_IS_GST_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_GST_MANAGER))
#define PINOS_IS_GST_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_GST_MANAGER))
#define PINOS_GST_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_GST_MANAGER, PinosGstManagerClass))
#define PINOS_GST_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_GST_MANAGER, PinosGstManager))
#define PINOS_GST_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_GST_MANAGER, PinosGstManagerClass))
#define PINOS_GST_MANAGER_CAST(obj) ((PinosGstManager*)(obj))
#define PINOS_GST_MANAGER_CLASS_CAST(klass) ((PinosGstManagerClass*)(klass))
typedef struct _PinosGstManager PinosGstManager;
typedef struct _PinosGstManagerClass PinosGstManagerClass;
typedef struct _PinosGstManagerPrivate PinosGstManagerPrivate;
struct _PinosGstManager {
GObject object;
PinosGstManagerPrivate *priv;
};
struct _PinosGstManagerClass {
GObjectClass parent_class;
};
GType pinos_gst_manager_get_type (void);
PinosGstManager * pinos_gst_manager_new (PinosDaemon *daemon);
G_END_DECLS
#endif /* __PINOS_GST_MANAGER_H__ */

View file

@ -1,71 +0,0 @@
#/* Pinos
* Copyright (C) 2016 Axis Communications AB
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include "gst-node-factory.h"
#include "gst-source.h"
G_DEFINE_TYPE (PinosGstNodeFactory, pinos_gst_node_factory, PINOS_TYPE_NODE_FACTORY);
static PinosNode *
factory_create_node (PinosNodeFactory * factory,
PinosDaemon * daemon,
const gchar * sender,
const gchar * name,
PinosProperties * properties)
{
PinosNode *node;
node = g_object_new (PINOS_TYPE_GST_SOURCE,
"daemon", daemon,
"sender", sender,
"name", name,
"properties", properties,
NULL);
return node;
}
static void
pinos_gst_node_factory_class_init (PinosGstNodeFactoryClass * klass)
{
PinosNodeFactoryClass *factory_class = PINOS_NODE_FACTORY_CLASS (klass);
factory_class->create_node = factory_create_node;
}
static void
pinos_gst_node_factory_init (PinosGstNodeFactory * factory)
{
}
PinosNodeFactory *
pinos_gst_node_factory_new (const gchar * name)
{
PinosNodeFactory *factory;
factory = g_object_new (PINOS_TYPE_GST_NODE_FACTORY,
"name", name,
NULL);
return factory;
}

View file

@ -1,55 +0,0 @@
/* Pinos
* Copyright (C) 2016 Axis Communications AB
*
* 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.
*/
#ifndef __PINOS_GST_NODE_FACTORY_H__
#define __PINOS_GST_NODE_FACTORY_H__
#include <glib-object.h>
#include <server/node-factory.h>
G_BEGIN_DECLS
#define PINOS_TYPE_GST_NODE_FACTORY (pinos_gst_node_factory_get_type ())
#define PINOS_IS_GST_NODE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_GST_NODE_FACTORY))
#define PINOS_IS_GST_NODE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_GST_NODE_FACTORY))
#define PINOS_GST_NODE_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_GST_NODE_FACTORY, PinosGstNodeFactoryClass))
#define PINOS_GST_NODE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_GST_NODE_FACTORY, PinosGstNodeFactory))
#define PINOS_GST_NODE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_GST_NODE_FACTORY, PinosGstNodeFactoryClass))
#define PINOS_GST_NODE_FACTORY_CAST(obj) ((PinosGstNodeFactory*)(obj))
#define PINOS_GST_NODE_FACTORY_CLASS_CAST(klass) ((PinosGstNodeFactoryClass*)(klass))
typedef struct _PinosGstNodeFactory PinosGstNodeFactory;
typedef struct _PinosGstNodeFactoryClass PinosGstNodeFactoryClass;
struct _PinosGstNodeFactory {
PinosNodeFactory object;
};
struct _PinosGstNodeFactoryClass {
PinosNodeFactoryClass parent_class;
};
GType pinos_gst_node_factory_get_type (void);
PinosNodeFactory * pinos_gst_node_factory_new (const gchar * name);
G_END_DECLS
#endif /* __PINOS_GST_NODE_FACTORY_H__ */

View file

@ -1,545 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <string.h>
#include <gst/gst.h>
#include <gio/gio.h>
#include <gst/net/net.h>
#include "gst-sink.h"
#define PINOS_GST_SINK_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_GST_SINK, PinosGstSinkPrivate))
typedef struct {
PinosGstSink *sink;
PinosPort *port;
GstElement *src;
GstElement *convert;
GstPad *srcpad;
GstPad *peerpad;
} SinkPortData;
struct _PinosGstSinkPrivate
{
gchar *convert_name;
GstElement *pipeline;
GstElement *mixer;
GstElement *element;
GList *ports;
GstCaps *possible_formats;
GstNetTimeProvider *provider;
};
enum {
PROP_0,
PROP_ELEMENT,
PROP_POSSIBLE_FORMATS,
PROP_MIXER,
PROP_CONVERT_NAME
};
G_DEFINE_TYPE (PinosGstSink, pinos_gst_sink, PINOS_TYPE_NODE);
static gboolean
bus_handler (GstBus *bus,
GstMessage *message,
gpointer user_data)
{
PinosNode *node = user_data;
PinosGstSinkPrivate *priv = PINOS_GST_SINK (node)->priv;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR:
{
GError *error;
gchar *debug;
gst_message_parse_error (message, &error, &debug);
g_warning ("got error %s (%s)\n", error->message, debug);
g_free (debug);
pinos_node_report_error (node, error);
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
break;
}
case GST_MESSAGE_NEW_CLOCK:
{
GstClock *clock;
PinosProperties *props;
gst_message_parse_new_clock (message, &clock);
GST_INFO ("got new clock %s", GST_OBJECT_NAME (clock));
g_object_get (node, "properties", &props, NULL);
pinos_properties_set (props, "gst.pipeline.clock", GST_OBJECT_NAME (clock));
g_object_set (node, "properties", props, NULL);
pinos_properties_free (props);
break;
}
case GST_MESSAGE_CLOCK_LOST:
{
GstClock *clock;
PinosProperties *props;
gst_message_parse_new_clock (message, &clock);
GST_INFO ("clock lost %s", GST_OBJECT_NAME (clock));
g_object_get (node, "properties", &props, NULL);
pinos_properties_set (props, "gst.pipeline.clock", NULL);
g_object_set (node, "properties", props, NULL);
pinos_properties_free (props);
gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
break;
}
default:
break;
}
return TRUE;
}
static gboolean
setup_pipeline (PinosGstSink *sink, GError **error)
{
PinosGstSinkPrivate *priv = sink->priv;
GstBus *bus;
g_debug ("gst-sink %p: setup pipeline", sink);
priv->pipeline = gst_pipeline_new (NULL);
g_object_set (priv->element, "sync", FALSE, NULL);
gst_bin_add (GST_BIN (priv->pipeline), priv->element);
if (priv->mixer) {
gst_bin_add (GST_BIN (priv->pipeline), priv->mixer);
gst_element_link (priv->mixer, priv->element);
}
bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
gst_bus_add_watch (bus, bus_handler, sink);
gst_object_unref (bus);
return TRUE;
}
#if 0
static gboolean
start_pipeline (PinosGstSink *sink, GError **error)
{
PinosGstSinkPrivate *priv = sink->priv;
#if 0
GstCaps *caps;
GstQuery *query;
gchar *str;
#endif
GstStateChangeReturn ret;
g_debug ("gst-sink %p: starting pipeline", sink);
ret = gst_element_set_state (priv->pipeline, GST_STATE_READY);
if (ret == GST_STATE_CHANGE_FAILURE)
goto ready_failed;
#if 0
query = gst_query_new_caps (NULL);
if (gst_element_query (priv->element, query)) {
gst_query_parse_caps_result (query, &caps);
gst_caps_replace (&priv->possible_formats, caps);
str = gst_caps_to_string (caps);
g_debug ("gst-sink %p: updated possible formats %s", sink, str);
g_free (str);
}
gst_query_unref (query);
#endif
return TRUE;
/* ERRORS */
ready_failed:
{
GST_ERROR_OBJECT (sink, "failed state change to READY");
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
if (error)
*error = g_error_new (G_IO_ERROR,
G_IO_ERROR_FAILED,
"Failed to start pipeline");
return FALSE;
}
}
#endif
static void
stop_pipeline (PinosGstSink *sink)
{
PinosGstSinkPrivate *priv = sink->priv;
g_debug ("gst-sink %p: stopping pipeline", sink);
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
g_clear_object (&priv->provider);
}
static void
destroy_pipeline (PinosGstSink *sink)
{
PinosGstSinkPrivate *priv = sink->priv;
g_debug ("gst-sink %p: destroy pipeline", sink);
stop_pipeline (sink);
g_clear_object (&priv->pipeline);
}
static gboolean
set_state (PinosNode *node,
PinosNodeState state)
{
PinosGstSinkPrivate *priv = PINOS_GST_SINK (node)->priv;
g_debug ("gst-sink %p: set state %s", node, pinos_node_state_as_string (state));
switch (state) {
case PINOS_NODE_STATE_SUSPENDED:
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
break;
case PINOS_NODE_STATE_INITIALIZING:
gst_element_set_state (priv->pipeline, GST_STATE_READY);
break;
case PINOS_NODE_STATE_IDLE:
gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
break;
case PINOS_NODE_STATE_RUNNING:
gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
break;
case PINOS_NODE_STATE_ERROR:
break;
}
pinos_node_update_state (node, state);
return TRUE;
}
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
PinosGstSink *sink = PINOS_GST_SINK (object);
PinosGstSinkPrivate *priv = sink->priv;
switch (prop_id) {
case PROP_ELEMENT:
g_value_set_object (value, priv->element);
break;
case PROP_POSSIBLE_FORMATS:
g_value_set_boxed (value, priv->possible_formats);
break;
case PROP_MIXER:
g_value_set_object (value, priv->mixer);
break;
case PROP_CONVERT_NAME:
g_value_set_string (value, priv->convert_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
PinosGstSink *sink = PINOS_GST_SINK (object);
PinosGstSinkPrivate *priv = sink->priv;
switch (prop_id) {
case PROP_ELEMENT:
priv->element = g_value_dup_object (value);
break;
case PROP_POSSIBLE_FORMATS:
priv->possible_formats = g_value_dup_boxed (value);
break;
case PROP_MIXER:
priv->mixer = g_value_dup_object (value);
break;
case PROP_CONVERT_NAME:
priv->convert_name = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
on_activate (PinosPort *port, gpointer user_data)
{
SinkPortData *data = user_data;
PinosGstSink *sink = data->sink;
PinosGstSinkPrivate *priv = sink->priv;
g_debug ("port %p: activate", port);
if (priv->mixer) {
data->peerpad = gst_element_get_request_pad (priv->mixer, "sink_%u");
} else {
data->peerpad = gst_element_get_static_pad (priv->element, "sink");
}
if (gst_pad_link (data->srcpad, data->peerpad) != GST_PAD_LINK_OK) {
g_clear_object (&data->peerpad);
return;
}
pinos_node_report_busy (PINOS_NODE (sink));
if (data->convert) {
gst_element_set_state (data->convert, GST_STATE_PLAYING);
}
gst_element_set_state (data->src, GST_STATE_PLAYING);
return;
}
static void
on_deactivate (PinosPort *port, gpointer user_data)
{
SinkPortData *data = user_data;
PinosGstSink *sink = data->sink;
PinosGstSinkPrivate *priv = sink->priv;
g_debug ("port %p: deactivate", port);
if (data->convert) {
gst_element_set_state (data->convert, GST_STATE_NULL);
}
gst_element_set_state (data->src, GST_STATE_NULL);
gst_pad_unlink (data->srcpad, data->peerpad);
if (priv->mixer)
gst_element_release_request_pad (priv->mixer, data->peerpad);
g_clear_object (&data->peerpad);
}
static void
free_sink_port_data (SinkPortData *data)
{
PinosGstSink *sink = data->sink;
PinosGstSinkPrivate *priv = sink->priv;
gst_element_set_state (data->src, GST_STATE_NULL);
gst_bin_remove (GST_BIN (priv->pipeline), data->src);
if (data->convert) {
gst_element_set_state (data->convert, GST_STATE_NULL);
gst_bin_remove (GST_BIN (priv->pipeline), data->convert);
}
if (data->peerpad)
gst_element_release_request_pad (priv->mixer, data->peerpad);
g_clear_object (&data->srcpad);
g_clear_object (&data->peerpad);
g_slice_free (SinkPortData, data);
}
static PinosPort *
add_port (PinosNode *node,
guint id,
GError **error)
{
PinosGstSink *sink = PINOS_GST_SINK (node);
PinosGstSinkPrivate *priv = sink->priv;
SinkPortData *data;
data = g_slice_new0 (SinkPortData);
data->sink = sink;
data->port = PINOS_NODE_CLASS (pinos_gst_sink_parent_class)
->add_port (node, id, error);
g_debug ("connecting signals");
g_signal_connect (data->port, "activate", (GCallback) on_activate, data);
g_signal_connect (data->port, "deactivate", (GCallback) on_deactivate, data);
data->src = gst_element_factory_make ("pinosportsrc", NULL);
g_object_set (data->src, "port", data->port, NULL);
gst_bin_add (GST_BIN (priv->pipeline), data->src);
if (priv->convert_name) {
data->convert = gst_element_factory_make (priv->convert_name, NULL);
gst_bin_add (GST_BIN (priv->pipeline), data->convert);
gst_element_link (data->src, data->convert);
data->srcpad = gst_element_get_static_pad (data->convert, "src");
} else {
data->srcpad = gst_element_get_static_pad (data->src, "src");
}
priv->ports = g_list_append (priv->ports, data);
return data->port;
}
static gboolean
remove_port (PinosNode *node,
PinosPort *port)
{
PinosGstSink *sink = PINOS_GST_SINK (node);
PinosGstSinkPrivate *priv = sink->priv;
GList *walk;
for (walk = priv->ports; walk; walk = g_list_next (walk)) {
SinkPortData *data = walk->data;
if (data->port == port) {
free_sink_port_data (data);
priv->ports = g_list_delete_link (priv->ports, walk);
break;
}
}
if (priv->ports == NULL)
pinos_node_report_idle (node);
return TRUE;
}
static void
sink_constructed (GObject * object)
{
PinosGstSink *sink = PINOS_GST_SINK (object);
G_OBJECT_CLASS (pinos_gst_sink_parent_class)->constructed (object);
setup_pipeline (sink, NULL);
}
static void
sink_finalize (GObject * object)
{
PinosGstSink *sink = PINOS_GST_SINK (object);
PinosGstSinkPrivate *priv = sink->priv;
destroy_pipeline (sink);
g_clear_pointer (&priv->possible_formats, gst_caps_unref);
G_OBJECT_CLASS (pinos_gst_sink_parent_class)->finalize (object);
}
static void
pinos_gst_sink_class_init (PinosGstSinkClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
PinosNodeClass *node_class = PINOS_NODE_CLASS (klass);
g_type_class_add_private (klass, sizeof (PinosGstSinkPrivate));
gobject_class->constructed = sink_constructed;
gobject_class->finalize = sink_finalize;
gobject_class->get_property = get_property;
gobject_class->set_property = set_property;
g_object_class_install_property (gobject_class,
PROP_ELEMENT,
g_param_spec_object ("element",
"Element",
"The element",
GST_TYPE_ELEMENT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_POSSIBLE_FORMATS,
g_param_spec_boxed ("possible-formats",
"Possible Formats",
"The possible formats",
GST_TYPE_CAPS,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_MIXER,
g_param_spec_object ("mixer",
"Mixer",
"The mixer element",
GST_TYPE_ELEMENT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_CONVERT_NAME,
g_param_spec_string ("convert-name",
"Convert name",
"The converter element name",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
node_class->set_state = set_state;
}
static void
pinos_gst_sink_init (PinosGstSink * sink)
{
sink->priv = PINOS_GST_SINK_GET_PRIVATE (sink);
}
PinosNode *
pinos_gst_sink_new (PinosDaemon *daemon,
const gchar *name,
PinosProperties *properties,
GstElement *element,
GstCaps *caps,
GstElement *mixer,
const gchar *convert_name)
{
PinosNode *node;
node = g_object_new (PINOS_TYPE_GST_SINK,
"daemon", daemon,
"name", name,
"properties", properties,
"element", element,
"possible-formats", caps,
"mixer", mixer,
"convert-name", convert_name,
NULL);
return node;
}

View file

@ -1,65 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_GST_SINK_H__
#define __PINOS_GST_SINK_H__
#include <glib-object.h>
#include <client/pinos.h>
#include <server/node.h>
G_BEGIN_DECLS
#define PINOS_TYPE_GST_SINK (pinos_gst_sink_get_type ())
#define PINOS_IS_GST_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_GST_SINK))
#define PINOS_IS_GST_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_GST_SINK))
#define PINOS_GST_SINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_GST_SINK, PinosGstSinkClass))
#define PINOS_GST_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_GST_SINK, PinosGstSink))
#define PINOS_GST_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_GST_SINK, PinosGstSinkClass))
#define PINOS_GST_SINK_CAST(obj) ((PinosGstSink*)(obj))
#define PINOS_GST_SINK_CLASS_CAST(klass) ((PinosGstSinkClass*)(klass))
typedef struct _PinosGstSink PinosGstSink;
typedef struct _PinosGstSinkClass PinosGstSinkClass;
typedef struct _PinosGstSinkPrivate PinosGstSinkPrivate;
struct _PinosGstSink {
PinosNode object;
PinosGstSinkPrivate *priv;
};
struct _PinosGstSinkClass {
PinosNodeClass parent_class;
};
GType pinos_gst_sink_get_type (void);
PinosNode * pinos_gst_sink_new (PinosDaemon *daemon,
const gchar *name,
PinosProperties *properties,
GstElement *element,
GstCaps *caps,
GstElement *mixer,
const gchar *convert_name);
G_END_DECLS
#endif /* __PINOS_GST_SINK_H__ */

View file

@ -1,691 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <string.h>
#include <gst/gst.h>
#include <gio/gio.h>
#include <gst/net/net.h>
#include "gst-source.h"
#define PINOS_GST_SOURCE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_GST_SOURCE, PinosGstSourcePrivate))
typedef struct {
PinosGstSource *source;
guint id;
PinosPort *port;
GstElement *convert;
GstElement *sink;
GstPad *peerpad;
GstPad *sinkpad;
} SourcePortData;
struct _PinosGstSourcePrivate
{
gchar *convert_name;
GstElement *pipeline;
GstElement *element;
GstElement *splitter;
GList *ports;
GstCaps *possible_formats;
GstNetTimeProvider *provider;
};
enum {
PROP_0,
PROP_ELEMENT,
PROP_POSSIBLE_FORMATS,
PROP_SPLITTER,
PROP_CONVERT_NAME
};
G_DEFINE_TYPE (PinosGstSource, pinos_gst_source, PINOS_TYPE_NODE);
static gboolean
bus_handler (GstBus *bus,
GstMessage *message,
gpointer user_data)
{
PinosNode *node = user_data;
PinosGstSourcePrivate *priv = PINOS_GST_SOURCE (node)->priv;
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR:
{
GError *error;
gchar *debug;
gst_message_parse_error (message, &error, &debug);
g_warning ("got error %s (%s)\n", error->message, debug);
g_free (debug);
pinos_node_report_error (node, error);
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
break;
}
case GST_MESSAGE_NEW_CLOCK:
{
GstClock *clock;
PinosProperties *props;
gst_message_parse_new_clock (message, &clock);
GST_INFO ("got new clock %s", GST_OBJECT_NAME (clock));
g_object_get (node, "properties", &props, NULL);
pinos_properties_set (props, "gst.pipeline.clock", GST_OBJECT_NAME (clock));
g_object_set (node, "properties", props, NULL);
pinos_properties_free (props);
break;
}
case GST_MESSAGE_CLOCK_LOST:
{
GstClock *clock;
PinosProperties *props;
gst_message_parse_new_clock (message, &clock);
GST_INFO ("clock lost %s", GST_OBJECT_NAME (clock));
g_object_get (node, "properties", &props, NULL);
pinos_properties_set (props, "gst.pipeline.clock", NULL);
g_object_set (node, "properties", props, NULL);
pinos_properties_free (props);
gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
break;
}
default:
break;
}
return TRUE;
}
static gboolean
setup_pipeline (PinosGstSource *source, GError **error)
{
PinosGstSourcePrivate *priv = source->priv;
GstBus *bus;
g_debug ("gst-source %p: setup pipeline", source);
priv->pipeline = gst_pipeline_new (NULL);
gst_pipeline_set_latency (GST_PIPELINE_CAST (priv->pipeline), 0);
gst_bin_add (GST_BIN (priv->pipeline), priv->element);
if (priv->splitter) {
gst_bin_add (GST_BIN (priv->pipeline), priv->splitter);
gst_element_link (priv->element, priv->splitter);
}
bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
gst_bus_add_watch (bus, bus_handler, source);
gst_object_unref (bus);
return TRUE;
}
#if 0
static gboolean
start_pipeline (PinosGstSource *source, GError **error)
{
PinosGstSourcePrivate *priv = source->priv;
GstCaps *caps;
GstQuery *query;
GstStateChangeReturn ret;
gchar *str;
g_debug ("gst-source %p: starting pipeline", source);
ret = gst_element_set_state (priv->pipeline, GST_STATE_READY);
if (ret == GST_STATE_CHANGE_FAILURE)
goto ready_failed;
query = gst_query_new_caps (NULL);
if (gst_element_query (priv->element, query)) {
gst_query_parse_caps_result (query, &caps);
gst_caps_replace (&priv->possible_formats, caps);
str = gst_caps_to_string (caps);
g_debug ("gst-source %p: updated possible formats %s", source, str);
g_free (str);
}
gst_query_unref (query);
return TRUE;
/* ERRORS */
ready_failed:
{
GST_ERROR_OBJECT (source, "failed state change to READY");
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
if (error)
*error = g_error_new (G_IO_ERROR,
G_IO_ERROR_FAILED,
"Failed to start pipeline");
return FALSE;
}
}
#endif
static void
stop_pipeline (PinosGstSource *source)
{
PinosGstSourcePrivate *priv = source->priv;
g_debug ("gst-source %p: stopping pipeline", source);
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
g_clear_object (&priv->provider);
}
static void
destroy_pipeline (PinosGstSource *source)
{
PinosGstSourcePrivate *priv = source->priv;
g_debug ("gst-source %p: destroy pipeline", source);
stop_pipeline (source);
g_clear_object (&priv->pipeline);
}
static gboolean
set_state (PinosNode *node,
PinosNodeState state)
{
PinosGstSourcePrivate *priv = PINOS_GST_SOURCE (node)->priv;
g_debug ("gst-source %p: set state %s", node, pinos_node_state_as_string (state));
switch (state) {
case PINOS_NODE_STATE_SUSPENDED:
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
break;
case PINOS_NODE_STATE_INITIALIZING:
gst_element_set_state (priv->pipeline, GST_STATE_READY);
break;
case PINOS_NODE_STATE_IDLE:
gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
break;
case PINOS_NODE_STATE_RUNNING:
{
GstQuery *query;
GstClock *clock;
gchar *address;
gint port;
PinosProperties *props;
GstClockTime base_time;
gboolean live;
GstClockTime min_latency, max_latency;
gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
gst_element_get_state (priv->pipeline, NULL, NULL, -1);
gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
gst_element_get_state (priv->pipeline, NULL, NULL, -1);
clock = gst_pipeline_get_clock (GST_PIPELINE (priv->pipeline));
base_time = gst_clock_get_time (clock);
if (priv->provider)
g_object_unref (priv->provider);
priv->provider = gst_net_time_provider_new (clock, NULL, 0);
g_object_get (priv->provider, "address", &address, "port", &port, NULL);
g_object_get (node, "properties", &props, NULL);
pinos_properties_set (props, "pinos.clock.type", "gst.net.time.provider");
pinos_properties_set (props, "pinos.clock.source", GST_OBJECT_NAME (clock));
pinos_properties_set (props, "pinos.clock.address", address);
pinos_properties_setf (props, "pinos.clock.port", "%d", port);
pinos_properties_setf (props, "pinos.clock.base-time", "%"G_GUINT64_FORMAT, base_time);
g_free (address);
gst_object_unref (clock);
query = gst_query_new_latency ();
if (gst_element_query (GST_ELEMENT_CAST (priv->pipeline), query)) {
gst_query_parse_latency (query, &live, &min_latency, &max_latency);
} else {
live = FALSE;
min_latency = 0;
max_latency = -1;
}
gst_query_unref (query);
GST_DEBUG_OBJECT (priv->pipeline,
"got min latency %" GST_TIME_FORMAT ", max latency %"
GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
GST_TIME_ARGS (max_latency), live);
pinos_properties_setf (props, "pinos.latency.is-live", "%d", live);
pinos_properties_setf (props, "pinos.latency.min", "%"G_GUINT64_FORMAT, min_latency);
pinos_properties_setf (props, "pinos.latency.max", "%"G_GUINT64_FORMAT, max_latency);
g_object_set (node, "properties", props, NULL);
pinos_properties_free (props);
break;
}
case PINOS_NODE_STATE_ERROR:
break;
}
pinos_node_update_state (node, state);
return TRUE;
}
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
PinosGstSource *source = PINOS_GST_SOURCE (object);
PinosGstSourcePrivate *priv = source->priv;
switch (prop_id) {
case PROP_ELEMENT:
g_value_set_object (value, priv->element);
break;
case PROP_POSSIBLE_FORMATS:
g_value_set_boxed (value, priv->possible_formats);
break;
case PROP_SPLITTER:
g_value_set_object (value, priv->splitter);
break;
case PROP_CONVERT_NAME:
g_value_set_string (value, priv->convert_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
PinosGstSource *source = PINOS_GST_SOURCE (object);
PinosGstSourcePrivate *priv = source->priv;
switch (prop_id) {
case PROP_ELEMENT:
priv->element = g_value_dup_object (value);
break;
case PROP_POSSIBLE_FORMATS:
priv->possible_formats = g_value_dup_boxed (value);
break;
case PROP_SPLITTER:
priv->splitter = g_value_dup_object (value);
break;
case PROP_CONVERT_NAME:
priv->convert_name = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
on_activate (PinosPort *port, gpointer user_data)
{
SourcePortData *data = user_data;
PinosGstSource *source = data->source;
PinosGstSourcePrivate *priv = source->priv;
if (priv->splitter) {
data->peerpad = gst_element_get_request_pad (priv->splitter, "src_%u");
} else {
data->peerpad = gst_element_get_static_pad (priv->element, "src");
}
if (gst_pad_link (data->peerpad, data->sinkpad) != GST_PAD_LINK_OK) {
g_clear_object (&data->peerpad);
return FALSE;
}
pinos_node_report_busy (PINOS_NODE (source));
gst_element_set_state (data->sink, GST_STATE_PLAYING);
if (data->convert) {
gst_element_set_state (data->convert, GST_STATE_PLAYING);
}
return TRUE;
}
static void
on_deactivate (PinosPort *port, gpointer user_data)
{
SourcePortData *data = user_data;
PinosGstSource *source = data->source;
PinosGstSourcePrivate *priv = source->priv;
gst_pad_unlink (data->peerpad, data->sinkpad);
if (priv->splitter)
gst_element_release_request_pad (priv->splitter, data->peerpad);
gst_element_set_state (data->sink, GST_STATE_NULL);
if (data->convert) {
gst_element_set_state (data->convert, GST_STATE_NULL);
}
g_clear_object (&data->peerpad);
pinos_node_report_idle (PINOS_NODE (source));
}
static void
free_source_port_data (SourcePortData *data)
{
PinosGstSource *source = data->source;
PinosGstSourcePrivate *priv = source->priv;
gst_element_set_state (data->sink, GST_STATE_NULL);
gst_bin_remove (GST_BIN (priv->pipeline), data->sink);
if (data->convert) {
gst_element_set_state (data->convert, GST_STATE_NULL);
gst_bin_remove (GST_BIN (priv->pipeline), data->convert);
}
if (data->peerpad)
gst_element_release_request_pad (priv->splitter, data->peerpad);
g_clear_object (&data->peerpad);
g_clear_object (&data->sinkpad);
g_slice_free (SourcePortData, data);
}
static gboolean
remove_port (PinosNode *node,
PinosPort *port)
{
PinosGstSource *source = PINOS_GST_SOURCE (node);
PinosGstSourcePrivate *priv = source->priv;
GList *walk;
for (walk = priv->ports; walk; walk = g_list_next (walk)) {
SourcePortData *data = walk->data;
if (data->port == port) {
free_source_port_data (data);
priv->ports = g_list_delete_link (priv->ports, walk);
break;
}
}
if (priv->ports == NULL)
pinos_node_report_idle (node);
return TRUE;
}
static void
source_constructed (GObject * object)
{
PinosGstSource *source = PINOS_GST_SOURCE (object);
PinosGstSourcePrivate *priv = source->priv;
G_OBJECT_CLASS (pinos_gst_source_parent_class)->constructed (object);
if (priv->element)
setup_pipeline (source, NULL);
}
static void
source_finalize (GObject * object)
{
PinosGstSource *source = PINOS_GST_SOURCE (object);
PinosGstSourcePrivate *priv = source->priv;
g_debug ("gst-source %p: dispose", source);
destroy_pipeline (source);
g_clear_pointer (&priv->possible_formats, gst_caps_unref);
G_OBJECT_CLASS (pinos_gst_source_parent_class)->finalize (object);
}
static gboolean
factory_filter (GstPluginFeature * feature, gpointer data)
{
guint rank;
const gchar *klass;
if (!GST_IS_ELEMENT_FACTORY (feature))
return FALSE;
rank = gst_plugin_feature_get_rank (feature);
if (rank < 1)
return FALSE;
klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY (feature),
GST_ELEMENT_METADATA_KLASS);
if (g_strcmp0 (klass, "Source/Video") && g_strcmp0 (klass, "Source/Audio"))
return FALSE;
return TRUE;
}
static GstElement *
create_best_element (GstCaps *caps)
{
GstElement *element = NULL;
GList *list, *item;
/* get factories from registry */
list = gst_registry_feature_filter (gst_registry_get (),
(GstPluginFeatureFilter) factory_filter,
FALSE, NULL);
list = g_list_sort (list,
(GCompareFunc) gst_plugin_feature_rank_compare_func);
/* loop through list and try to find factory that best matches caps,
* following the pattern from GstAutoDetect */
for (item = list; item != NULL; item = item->next) {
GstElementFactory *f = GST_ELEMENT_FACTORY (item->data);
GstElement *el;
GstPad *el_pad;
GstCaps *el_caps = NULL;
gboolean match = FALSE;
GstStateChangeReturn ret;
if ((el = gst_element_factory_create (f, NULL))) {
el_pad = gst_element_get_static_pad (el, "src");
el_caps = gst_pad_query_caps (el_pad, NULL);
gst_object_unref (el_pad);
match = gst_caps_can_intersect (caps, el_caps);
gst_caps_unref (el_caps);
if (!match) {
gst_object_unref (el);
continue;
}
}
ret = gst_element_set_state (el, GST_STATE_READY);
if (ret == GST_STATE_CHANGE_SUCCESS) {
element = el;
g_debug ("element %p selected", element);
break;
}
gst_element_set_state (el, GST_STATE_NULL);
gst_object_unref (el);
}
return element;
}
static PinosPort *
add_port (PinosNode *node,
guint id,
GError **error)
{
PinosGstSource *source = PINOS_GST_SOURCE (node);
PinosGstSourcePrivate *priv = source->priv;
SourcePortData *data;
PinosProperties *props = NULL;
if (priv->element == NULL) {
GstCaps *caps;
caps = NULL;
priv->element = create_best_element (caps);
gst_caps_unref (caps);
if (priv->element) {
props = pinos_properties_new (NULL, NULL);
pinos_properties_set (props, "autoconnect", "0");
setup_pipeline (source, NULL);
}
}
data = g_slice_new0 (SourcePortData);
data->source = source;
data->port = PINOS_NODE_CLASS (pinos_gst_source_parent_class)
->add_port (node, id, error);
g_debug ("connecting signals");
g_signal_connect (data->port, "activate", (GCallback) on_activate, data);
g_signal_connect (data->port, "deactivate", (GCallback) on_deactivate, data);
data->sink = gst_element_factory_make ("pinosportsink", NULL);
g_object_set (data->sink, "sync", TRUE,
"enable-last-sample", FALSE,
"qos", FALSE,
"port", data->port,
NULL);
gst_bin_add (GST_BIN (priv->pipeline), data->sink);
if (priv->convert_name) {
data->convert = gst_element_factory_make (priv->convert_name, NULL);
gst_bin_add (GST_BIN (priv->pipeline), data->convert);
gst_element_link (data->convert, data->sink);
data->sinkpad = gst_element_get_static_pad (data->convert, "sink");
} else {
data->sinkpad = gst_element_get_static_pad (data->sink, "sink");
}
priv->ports = g_list_append (priv->ports, data);
return data->port;
}
static void
pinos_gst_source_class_init (PinosGstSourceClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
PinosNodeClass *node_class = PINOS_NODE_CLASS (klass);
g_type_class_add_private (klass, sizeof (PinosGstSourcePrivate));
gobject_class->constructed = source_constructed;
gobject_class->finalize = source_finalize;
gobject_class->get_property = get_property;
gobject_class->set_property = set_property;
g_object_class_install_property (gobject_class,
PROP_ELEMENT,
g_param_spec_object ("element",
"Element",
"The element",
GST_TYPE_ELEMENT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_POSSIBLE_FORMATS,
g_param_spec_boxed ("possible-formats",
"Possible Formats",
"The possible formats",
GST_TYPE_CAPS,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_SPLITTER,
g_param_spec_object ("splitter",
"Splitter",
"The splitter element",
GST_TYPE_ELEMENT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_CONVERT_NAME,
g_param_spec_string ("convert-name",
"Convert name",
"The converter element name",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
node_class->set_state = set_state;
node_class->add_port = add_port;
node_class->remove_port = remove_port;
}
static void
pinos_gst_source_init (PinosGstSource * source)
{
source->priv = PINOS_GST_SOURCE_GET_PRIVATE (source);
}
PinosNode *
pinos_gst_source_new (PinosDaemon *daemon,
const gchar *name,
PinosProperties *properties,
GstElement *element,
GstCaps *caps,
GstElement *splitter,
const gchar *convert_name)
{
PinosNode *node;
node = g_object_new (PINOS_TYPE_GST_SOURCE,
"daemon", daemon,
"name", name,
"properties", properties,
"element", element,
"possible-formats", caps,
"splitter", splitter,
"convert-name", convert_name,
NULL);
return node;
}

View file

@ -1,65 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_GST_SOURCE_H__
#define __PINOS_GST_SOURCE_H__
#include <glib-object.h>
#include <client/pinos.h>
#include <server/node.h>
G_BEGIN_DECLS
#define PINOS_TYPE_GST_SOURCE (pinos_gst_source_get_type ())
#define PINOS_IS_GST_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_GST_SOURCE))
#define PINOS_IS_GST_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_GST_SOURCE))
#define PINOS_GST_SOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_GST_SOURCE, PinosGstSourceClass))
#define PINOS_GST_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_GST_SOURCE, PinosGstSource))
#define PINOS_GST_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_GST_SOURCE, PinosGstSourceClass))
#define PINOS_GST_SOURCE_CAST(obj) ((PinosGstSource*)(obj))
#define PINOS_GST_SOURCE_CLASS_CAST(klass) ((PinosGstSourceClass*)(klass))
typedef struct _PinosGstSource PinosGstSource;
typedef struct _PinosGstSourceClass PinosGstSourceClass;
typedef struct _PinosGstSourcePrivate PinosGstSourcePrivate;
struct _PinosGstSource {
PinosNode object;
PinosGstSourcePrivate *priv;
};
struct _PinosGstSourceClass {
PinosNodeClass parent_class;
};
GType pinos_gst_source_get_type (void);
PinosNode * pinos_gst_source_new (PinosDaemon *daemon,
const gchar *name,
PinosProperties *properties,
GstElement *element,
GstCaps *caps,
GstElement *mixer,
const gchar *converter);
G_END_DECLS
#endif /* __PINOS_GST_SOURCE_H__ */

View file

@ -1,27 +0,0 @@
pinos_module_spa_headers = [
'spa-alsa-monitor.h',
'spa-audiotestsrc.h',
'spa-v4l2-monitor.h',
'spa-videotestsrc.h',
]
pinos_module_spa_sources = [
'module.c',
'spa-alsa-monitor.c',
'spa-audiotestsrc.c',
'spa-v4l2-monitor.c',
'spa-videotestsrc.c',
]
pinos_module_spa_c_args = [
'-DHAVE_CONFIG_H',
'-D_GNU_SOURCE',
]
pinos_module_spa = shared_library('pinos-module-spa', pinos_module_spa_sources,
c_args : pinos_module_spa_c_args,
include_directories : [configinc, pinosinc, spa_inc],
link_with : spalib,
dependencies : [gobject_dep, gmodule_dep, glib_dep, gio_dep, mathlib, dl_lib, pinos_dep, pinoscore_dep],
)

View file

@ -1,42 +0,0 @@
/* Pinos
* Copyright (C) 2016 Axis Communications <dev-gstreamer@axis.com>
* @author Linus Svensson <linus.svensson@axis.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 <server/daemon.h>
#include <server/module.h>
#include "gst-manager.h"
#include "gst-node-factory.h"
gboolean pinos__module_init (PinosModule *module, const gchar * args);
G_MODULE_EXPORT gboolean
pinos__module_init (PinosModule * module, G_GNUC_UNUSED const gchar * args)
{
PinosNodeFactory *factory;
pinos_gst_manager_new (module->daemon);
factory = pinos_gst_node_factory_new ("gst-node-factory");
pinos_daemon_add_node_factory (module->daemon, factory);
g_object_unref (factory);
return TRUE;
}

View file

@ -1,61 +0,0 @@
#subdir('gst')
subdir('spa')
pinos_module_c_args = [
'-DHAVE_CONFIG_H',
'-D_GNU_SOURCE',
]
pinos_module_flatpak = shared_library('pinos-module-flatpak', [ 'module-flatpak.c' ],
c_args : pinos_module_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
install_dir : modules_install_dir,
dependencies : [dbus_dep, mathlib, dl_lib, pinos_dep, pinoscore_dep],
)
pinos_module_autolink = shared_library('pinos-module-autolink', [ 'module-autolink.c' ],
c_args : pinos_module_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
install_dir : modules_install_dir,
dependencies : [mathlib, dl_lib, pinos_dep, pinoscore_dep],
)
pinos_module_mixer = shared_library('pinos-module-mixer', [ 'module-mixer.c' ],
c_args : pinos_module_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
install_dir : modules_install_dir,
dependencies : [mathlib, dl_lib, pinos_dep, pinoscore_dep],
)
pinos_module_protocol_dbus = shared_library('pinos-module-protocol-dbus', [ 'module-protocol-dbus.c', gdbus_target ],
c_args : pinos_module_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
install_dir : modules_install_dir,
dependencies : [glib_dep, gio_dep, mathlib, dl_lib, pinos_dep, pinoscore_dep],
)
pinos_module_protocol_native = shared_library('pinos-module-protocol-native', [ 'module-protocol-native.c' ],
c_args : pinos_module_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
install_dir : modules_install_dir,
dependencies : [mathlib, dl_lib, pinos_dep, pinoscore_dep],
)
pinos_module_suspend_on_idle = shared_library('pinos-module-suspend-on-idle', [ 'module-suspend-on-idle.c' ],
c_args : pinos_module_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
install_dir : modules_install_dir,
dependencies : [mathlib, dl_lib, pinos_dep, pinoscore_dep],
)

View file

@ -1,442 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <string.h>
#include <stdio.h>
#include <errno.h>
#include "config.h"
#include "pinos/client/interfaces.h"
#include "pinos/server/core.h"
#include "pinos/server/module.h"
#include "pinos/server/client-node.h"
typedef struct {
PinosCore *core;
PinosProperties *properties;
PinosListener global_added;
PinosListener global_removed;
SpaList client_list;
} ModuleImpl;
typedef struct {
ModuleImpl *impl;
PinosClient *client;
SpaList link;
PinosListener resource_added;
PinosListener resource_removed;
SpaList node_list;
} ClientInfo;
typedef struct {
ModuleImpl *impl;
ClientInfo *info;
PinosNode *node;
PinosResource *resource;
SpaList link;
PinosListener state_changed;
PinosListener port_added;
PinosListener port_removed;
PinosListener port_unlinked;
PinosListener link_state_changed;
} NodeInfo;
static NodeInfo *
find_node_info (ClientInfo *cinfo, PinosNode *node)
{
NodeInfo *info;
spa_list_for_each (info, &cinfo->node_list, link) {
if (info->node == node)
return info;
}
return NULL;
}
static ClientInfo *
find_client_info (ModuleImpl *impl, PinosClient *client)
{
ClientInfo *info;
spa_list_for_each (info, &impl->client_list, link) {
if (info->client == client)
return info;
}
return NULL;
}
static void
node_info_free (NodeInfo *info)
{
spa_list_remove (&info->link);
pinos_signal_remove (&info->state_changed);
pinos_signal_remove (&info->port_added);
pinos_signal_remove (&info->port_removed);
pinos_signal_remove (&info->port_unlinked);
pinos_signal_remove (&info->link_state_changed);
free (info);
}
static void
client_info_free (ClientInfo *cinfo)
{
NodeInfo *info, *tmp;
spa_list_remove (&cinfo->link);
pinos_signal_remove (&cinfo->resource_added);
pinos_signal_remove (&cinfo->resource_removed);
spa_list_for_each_safe (info, tmp, &cinfo->node_list, link)
node_info_free (info);
free (cinfo);
}
static void try_link_port (PinosNode *node, PinosPort *port, NodeInfo *info);
static void
on_link_port_unlinked (PinosListener *listener,
PinosLink *link,
PinosPort *port)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, port_unlinked);
ModuleImpl *impl = info->impl;
pinos_log_debug ("module %p: link %p: port %p unlinked", impl, link, port);
if (port->direction == PINOS_DIRECTION_OUTPUT && link->input)
try_link_port (link->input->node, link->input, info);
}
static void
on_link_state_changed (PinosListener *listener,
PinosLink *link,
PinosLinkState old,
PinosLinkState state)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, link_state_changed);
ModuleImpl *impl = info->impl;
switch (state) {
case PINOS_LINK_STATE_ERROR:
{
PinosResource *resource;
pinos_log_debug ("module %p: link %p: state error: %s", impl, link, link->error);
spa_list_for_each (resource, &link->resource_list, link) {
pinos_core_notify_error (resource->client->core_resource,
resource->id,
SPA_RESULT_ERROR,
link->error);
}
if (info->info->client) {
pinos_core_notify_error (info->info->client->core_resource,
info->resource->id,
SPA_RESULT_ERROR,
link->error);
}
break;
}
case PINOS_LINK_STATE_UNLINKED:
pinos_log_debug ("module %p: link %p: unlinked", impl, link);
break;
case PINOS_LINK_STATE_INIT:
case PINOS_LINK_STATE_NEGOTIATING:
case PINOS_LINK_STATE_ALLOCATING:
case PINOS_LINK_STATE_PAUSED:
case PINOS_LINK_STATE_RUNNING:
break;
}
}
static void
try_link_port (PinosNode *node,
PinosPort *port,
NodeInfo *info)
{
ModuleImpl *impl = info->impl;
PinosProperties *props;
const char *str;
uint32_t path_id;
char *error = NULL;
PinosLink *link;
PinosPort *target;
props = node->properties;
if (props == NULL) {
pinos_log_debug ("module %p: node has no properties", impl);
return;
}
str = pinos_properties_get (props, "pinos.target.node");
if (str != NULL)
path_id = atoi (str);
else {
str = pinos_properties_get (props, "pinos.autoconnect");
if (str == NULL || atoi (str) == 0) {
pinos_log_debug ("module %p: node does not need autoconnect", impl);
return;
}
path_id = SPA_ID_INVALID;
}
pinos_log_debug ("module %p: try to find and link to node '%d'", impl, path_id);
target = pinos_core_find_port (impl->core,
port,
path_id,
NULL,
0,
NULL,
&error);
if (target == NULL)
goto error;
if (port->direction == PINOS_DIRECTION_OUTPUT)
link = pinos_port_link (port, target, NULL, NULL, &error);
else
link = pinos_port_link (target, port, NULL, NULL, &error);
if (link == NULL)
goto error;
pinos_signal_add (&link->port_unlinked, &info->port_unlinked, on_link_port_unlinked);
pinos_signal_add (&link->state_changed, &info->link_state_changed, on_link_state_changed);
pinos_link_activate (link);
return;
error:
{
pinos_log_error ("module %p: can't link node '%s'", impl, error);
if (info->info->client && info->info->client->core_resource) {
pinos_core_notify_error (info->info->client->core_resource,
info->resource->id,
SPA_RESULT_ERROR,
error);
}
free (error);
return;
}
}
static void
on_port_added (PinosListener *listener,
PinosNode *node,
PinosPort *port)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, port_added);
try_link_port (node, port, info);
}
static void
on_port_removed (PinosListener *listener,
PinosNode *node,
PinosPort *port)
{
}
static void
on_node_created (PinosNode *node,
NodeInfo *info)
{
PinosPort *port;
spa_list_for_each (port, &node->input_ports, link)
on_port_added (&info->port_added, node, port);
spa_list_for_each (port, &node->output_ports, link)
on_port_added (&info->port_added, node, port);
}
static void
on_state_changed (PinosListener *listener,
PinosNode *node,
PinosNodeState old,
PinosNodeState state)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, state_changed);
if (old == PINOS_NODE_STATE_CREATING && state == PINOS_NODE_STATE_SUSPENDED)
on_node_created (node, info);
}
static void
on_node_added (ModuleImpl *impl,
PinosNode *node,
PinosResource *resource,
ClientInfo *cinfo)
{
NodeInfo *info;
info = calloc (1, sizeof (NodeInfo));
info->impl = impl;
info->node = node;
info->resource = resource;
info->info = cinfo;
spa_list_insert (cinfo->node_list.prev, &info->link);
spa_list_init (&info->port_unlinked.link);
spa_list_init (&info->link_state_changed.link);
pinos_signal_add (&node->port_added, &info->port_added, on_port_added);
pinos_signal_add (&node->port_removed, &info->port_removed, on_port_removed);
pinos_signal_add (&node->state_changed, &info->state_changed, on_state_changed);
pinos_log_debug ("module %p: node %p added", impl, node);
if (node->state > PINOS_NODE_STATE_CREATING)
on_node_created (node, info);
}
static void
on_resource_added (PinosListener *listener,
PinosClient *client,
PinosResource *resource)
{
ClientInfo *cinfo = SPA_CONTAINER_OF (listener, ClientInfo, resource_added);
ModuleImpl *impl = cinfo->impl;
if (resource->type == impl->core->type.client_node) {
PinosClientNode *cnode = resource->object;
on_node_added (impl, cnode->node, resource, cinfo);
}
}
static void
on_resource_removed (PinosListener *listener,
PinosClient *client,
PinosResource *resource)
{
ClientInfo *cinfo = SPA_CONTAINER_OF (listener, ClientInfo, resource_removed);
ModuleImpl *impl = cinfo->impl;
if (resource->type == impl->core->type.client_node) {
PinosClientNode *cnode = resource->object;
NodeInfo *ninfo;
if ((ninfo = find_node_info (cinfo, cnode->node)))
node_info_free (ninfo);
pinos_log_debug ("module %p: node %p removed", impl, cnode->node);
}
}
static void
on_global_added (PinosListener *listener,
PinosCore *core,
PinosGlobal *global)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_added);
if (global->type == impl->core->type.client) {
PinosClient *client = global->object;
ClientInfo *cinfo;
cinfo = calloc (1, sizeof (ClientInfo));
cinfo->impl = impl;
cinfo->client = global->object;
spa_list_init (&cinfo->node_list);
spa_list_insert (impl->client_list.prev, &cinfo->link);
pinos_signal_add (&client->resource_added, &cinfo->resource_added, on_resource_added);
pinos_signal_add (&client->resource_removed, &cinfo->resource_removed, on_resource_removed);
pinos_log_debug ("module %p: client %p added", impl, cinfo->client);
}
}
static void
on_global_removed (PinosListener *listener,
PinosCore *core,
PinosGlobal *global)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_removed);
if (global->type == impl->core->type.client) {
PinosClient *client = global->object;
ClientInfo *cinfo;
if ((cinfo = find_client_info (impl, client)))
client_info_free (cinfo);
pinos_log_debug ("module %p: client %p removed", impl, client);
}
}
/**
* module_new:
* @core: #PinosCore
* @properties: #PinosProperties
*
* Make a new #ModuleImpl object with given @properties
*
* Returns: a new #ModuleImpl
*/
static ModuleImpl *
module_new (PinosCore *core,
PinosProperties *properties)
{
ModuleImpl *impl;
impl = calloc (1, sizeof (ModuleImpl));
pinos_log_debug ("module %p: new", impl);
impl->core = core;
impl->properties = properties;
spa_list_init (&impl->client_list);
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
return impl;
}
#if 0
static void
module_destroy (ModuleImpl *impl)
{
pinos_log_debug ("module %p: destroy", impl);
pinos_global_destroy (impl->global);
pinos_signal_remove (&impl->global_added);
pinos_signal_remove (&impl->global_removed);
pinos_signal_remove (&impl->port_added);
pinos_signal_remove (&impl->port_removed);
pinos_signal_remove (&impl->port_unlinked);
pinos_signal_remove (&impl->link_state_changed);
free (impl);
}
#endif
bool
pinos__module_init (PinosModule * module, const char * args)
{
module->user_data = module_new (module->core, NULL);
return true;
}

View file

@ -1,215 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <string.h>
#include <stdio.h>
#include <errno.h>
#include "config.h"
#include "pinos/server/core.h"
#include "pinos/server/module.h"
typedef struct {
PinosCore *core;
PinosProperties *properties;
PinosListener global_added;
PinosListener global_removed;
SpaList node_list;
} ModuleImpl;
typedef struct {
ModuleImpl *impl;
PinosNode *node;
SpaList link;
PinosListener node_state_request;
PinosListener node_state_changed;
SpaSource *idle_timeout;
} NodeInfo;
static NodeInfo *
find_node_info (ModuleImpl *impl, PinosNode *node)
{
NodeInfo *info;
spa_list_for_each (info, &impl->node_list, link) {
if (info->node == node)
return info;
}
return NULL;
}
static void
remove_idle_timeout (NodeInfo *info)
{
if (info->idle_timeout) {
pinos_loop_destroy_source (info->impl->core->main_loop->loop, info->idle_timeout);
info->idle_timeout = NULL;
}
}
static void
node_info_free (NodeInfo *info)
{
spa_list_remove (&info->link);
remove_idle_timeout (info);
pinos_signal_remove (&info->node_state_request);
pinos_signal_remove (&info->node_state_changed);
free (info);
}
static void
idle_timeout (SpaLoopUtils *utils,
SpaSource *source,
void *data)
{
NodeInfo *info = data;
pinos_log_debug ("module %p: node %p idle timeout", info->impl, info->node);
remove_idle_timeout (info);
pinos_node_set_state (info->node, PINOS_NODE_STATE_SUSPENDED);
}
static void
on_node_state_request (PinosListener *listener,
PinosNode *node,
PinosNodeState state)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, node_state_request);
remove_idle_timeout (info);
}
static void
on_node_state_changed (PinosListener *listener,
PinosNode *node,
PinosNodeState old,
PinosNodeState state)
{
NodeInfo *info = SPA_CONTAINER_OF (listener, NodeInfo, node_state_changed);
ModuleImpl *impl = info->impl;
if (state != PINOS_NODE_STATE_IDLE) {
remove_idle_timeout (info);
} else {
struct timespec value;
pinos_log_debug ("module %p: node %p became idle", impl, node);
info->idle_timeout = pinos_loop_add_timer (impl->core->main_loop->loop,
idle_timeout,
info);
value.tv_sec = 3;
value.tv_nsec = 0;
pinos_loop_update_timer (impl->core->main_loop->loop,
info->idle_timeout,
&value,
NULL,
false);
}
}
static void
on_global_added (PinosListener *listener,
PinosCore *core,
PinosGlobal *global)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_added);
if (global->type == impl->core->type.node) {
PinosNode *node = global->object;
NodeInfo *info;
info = calloc (1, sizeof (NodeInfo));
info->impl = impl;
info->node = node;
spa_list_insert (impl->node_list.prev, &info->link);
pinos_signal_add (&node->state_request, &info->node_state_request, on_node_state_request);
pinos_signal_add (&node->state_changed, &info->node_state_changed, on_node_state_changed);
pinos_log_debug ("module %p: node %p added", impl, node);
}
}
static void
on_global_removed (PinosListener *listener,
PinosCore *core,
PinosGlobal *global)
{
ModuleImpl *impl = SPA_CONTAINER_OF (listener, ModuleImpl, global_removed);
if (global->type == impl->core->type.node) {
PinosNode *node = global->object;
NodeInfo *info;
if ((info = find_node_info (impl, node)))
node_info_free (info);
pinos_log_debug ("module %p: node %p removed", impl, node);
}
}
/**
* module_new:
* @core: #PinosCore
* @properties: #PinosProperties
*
* Make a new #ModuleImpl object with given @properties
*
* Returns: a new #ModuleImpl
*/
static ModuleImpl *
module_new (PinosCore *core,
PinosProperties *properties)
{
ModuleImpl *impl;
impl = calloc (1, sizeof (ModuleImpl));
pinos_log_debug ("module %p: new", impl);
impl->core = core;
impl->properties = properties;
spa_list_init (&impl->node_list);
pinos_signal_add (&core->global_added, &impl->global_added, on_global_added);
pinos_signal_add (&core->global_removed, &impl->global_removed, on_global_removed);
return impl;
}
#if 0
static void
module_destroy (ModuleImpl *impl)
{
pinos_log_debug ("module %p: destroy", impl);
pinos_global_destroy (impl->global);
free (impl);
}
#endif
bool
pinos__module_init (PinosModule * module, const char * args)
{
module_new (module->core, NULL);
return true;
}

View file

@ -1,24 +0,0 @@
pinos_module_spa_headers = [
'spa-node.h',
'spa-monitor.h',
]
pinos_module_spa_sources = [
'module.c',
'spa-node.c',
'spa-monitor.c',
]
pinos_module_spa_c_args = [
'-DHAVE_CONFIG_H',
'-D_GNU_SOURCE',
]
pinos_module_spa = shared_library('pinos-module-spa', pinos_module_spa_sources,
c_args : pinos_module_spa_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
install_dir : '@0@/pinos-0.1'.format(get_option('libdir')),
dependencies : [mathlib, dl_lib, pinos_dep, pinoscore_dep],
)

View file

@ -1,57 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_SPA_NODE_H__
#define __PINOS_SPA_NODE_H__
#include <pinos/server/core.h>
#include <pinos/server/node.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosSpaNode PinosSpaNode;
struct _PinosSpaNode {
PinosNode *node;
char *lib;
char *factory_name;
SpaHandle *handle;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosSpaNode *node));
};
typedef SpaResult (*SetupNode) (PinosCore *core,
SpaNode *spa_node,
PinosProperties *pinos_props);
PinosSpaNode * pinos_spa_node_load (PinosCore *core,
const char *lib,
const char *factory_name,
const char *name,
PinosProperties *properties,
SetupNode setup_func);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_SPA_NODE_H__ */

View file

@ -1,72 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_ACCESS_H__
#define __PINOS_ACCESS_H__
#ifdef __cplusplus
extern "C" {
#endif
#define PINOS_TYPE__Access "Pinos:Object:Access"
#define PINOS_TYPE_ACCESS_BASE PINOS_TYPE__Access ":"
#include <pinos/client/sig.h>
typedef struct _PinosAccess PinosAccess;
typedef struct _PinosAccessData PinosAccessData;
#include <pinos/server/client.h>
#include <pinos/server/resource.h>
struct _PinosAccessData {
SpaResult res;
PinosResource *resource;
void * (*async_copy) (PinosAccessData *data, size_t size);
void (*complete_cb) (PinosAccessData *data);
void (*free_cb) (PinosAccessData *data);
void * user_data;
};
/**
* PinosAccess:
*
* Pinos Access support struct.
*/
struct _PinosAccess {
SpaResult (*view_global) (PinosAccess *access,
PinosClient *client,
PinosGlobal *global);
SpaResult (*create_node) (PinosAccess *access,
PinosAccessData *data,
const char *factory_name,
const char *name,
PinosProperties *properties);
SpaResult (*create_client_node) (PinosAccess *access,
PinosAccessData *data,
const char *name,
PinosProperties *properties);
};
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_ACCESS_H__ */

View file

@ -1,63 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_CLIENT_NODE_H__
#define __PINOS_CLIENT_NODE_H__
#include <pinos/server/node.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PINOS_TYPE__ClientNode "Pinos:Object:ClientNode"
#define PINOS_TYPE_CLIENT_NODE_BASE PINOS_TYPE__ClientNode ":"
typedef struct _PinosClientNode PinosClientNode;
/**
* PinosClientNode:
*
* Pinos client node interface
*/
struct _PinosClientNode {
PinosNode *node;
PinosClient *client;
PinosResource *resource;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosClientNode *node));
};
PinosClientNode * pinos_client_node_new (PinosClient *client,
uint32_t id,
const char *name,
PinosProperties *properties);
void pinos_client_node_destroy (PinosClientNode *node);
SpaResult pinos_client_node_get_fds (PinosClientNode *node,
int *readfd,
int *writefd);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_CLIENT_NODE_H__ */

View file

@ -1,88 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_CLIENT_H__
#define __PINOS_CLIENT_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosClient PinosClient;
#include <sys/socket.h>
#include <pinos/client/introspect.h>
#include <pinos/client/properties.h>
#include <pinos/client/sig.h>
#include <pinos/server/core.h>
#include <pinos/server/resource.h>
/**
* PinosClient:
*
* Pinos client object class.
*/
struct _PinosClient {
PinosCore *core;
SpaList link;
PinosGlobal *global;
PinosProperties *properties;
PINOS_SIGNAL (properties_changed, (PinosListener *listener,
PinosClient *client));
PinosClientInfo info;
bool ucred_valid;
struct ucred ucred;
void *protocol_private;
PinosResource *core_resource;
PinosMap objects;
uint32_t n_types;
PinosMap types;
SpaList resource_list;
PINOS_SIGNAL (resource_added, (PinosListener *listener,
PinosClient *client,
PinosResource *resource));
PINOS_SIGNAL (resource_removed, (PinosListener *listener,
PinosClient *client,
PinosResource *resource));
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosClient *client));
};
PinosClient * pinos_client_new (PinosCore *core,
struct ucred *ucred,
PinosProperties *properties);
void pinos_client_destroy (PinosClient *client);
void pinos_client_update_properties (PinosClient *client,
const SpaDict *dict);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_CLIENT_H__ */

View file

@ -1,145 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_CORE_H__
#define __PINOS_CORE_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosCore PinosCore;
typedef struct _PinosGlobal PinosGlobal;
#include <spa/log.h>
#include <pinos/client/type.h>
#include <pinos/server/access.h>
#include <pinos/server/main-loop.h>
#include <pinos/server/data-loop.h>
#include <pinos/server/node.h>
#include <pinos/server/link.h>
#include <pinos/server/node-factory.h>
typedef SpaResult (*PinosBindFunc) (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id);
struct _PinosGlobal {
PinosCore *core;
PinosClient *owner;
SpaList link;
uint32_t id;
uint32_t type;
uint32_t version;
void *object;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosGlobal *global));
};
/**
* PinosCore:
*
* Pinos core object class.
*/
struct _PinosCore {
PinosGlobal *global;
PinosCoreInfo info;
PinosProperties *properties;
PinosType type;
PinosAccess *access;
PinosMap objects;
SpaList resource_list;
SpaList registry_resource_list;
SpaList global_list;
SpaList client_list;
SpaList node_list;
SpaList node_factory_list;
SpaList link_list;
PinosMainLoop *main_loop;
PinosDataLoop *data_loop;
SpaSupport *support;
uint32_t n_support;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosCore *core));
PINOS_SIGNAL (global_added, (PinosListener *listener,
PinosCore *core,
PinosGlobal *global));
PINOS_SIGNAL (global_removed, (PinosListener *listener,
PinosCore *core,
PinosGlobal *global));
};
PinosCore * pinos_core_new (PinosMainLoop *main_loop,
PinosProperties *props);
void pinos_core_destroy (PinosCore *core);
void pinos_core_update_properties (PinosCore *core,
const SpaDict *dict);
bool pinos_core_add_global (PinosCore *core,
PinosClient *owner,
uint32_t type,
uint32_t version,
void *object,
PinosBindFunc bind,
PinosGlobal **global);
SpaResult pinos_global_bind (PinosGlobal *global,
PinosClient *client,
uint32_t version,
uint32_t id);
void pinos_global_destroy (PinosGlobal *global);
SpaFormat * pinos_core_find_format (PinosCore *core,
PinosPort *output,
PinosPort *input,
PinosProperties *props,
uint32_t n_format_filters,
SpaFormat **format_filters,
char **error);
PinosPort * pinos_core_find_port (PinosCore *core,
PinosPort *other_port,
uint32_t id,
PinosProperties *props,
uint32_t n_format_filters,
SpaFormat **format_filters,
char **error);
PinosNodeFactory * pinos_core_find_node_factory (PinosCore *core,
const char *name);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_CORE_H__ */

View file

@ -1,96 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_LINK_H__
#define __PINOS_LINK_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosLink PinosLink;
#include <spa/ringbuffer.h>
#include <pinos/client/mem.h>
#include <pinos/server/core.h>
#include <pinos/server/port.h>
#include <pinos/server/main-loop.h>
/**
* PinosLink:
*
* Pinos link interface.
*/
struct _PinosLink {
PinosCore *core;
SpaList link;
PinosGlobal *global;
PinosProperties *properties;
PinosLinkState state;
char *error;
PINOS_SIGNAL (state_changed, (PinosListener *listener,
PinosLink *link,
PinosLinkState old,
PinosLinkState state));
PINOS_SIGNAL (destroy_signal, (PinosListener *,
PinosLink *));
PINOS_SIGNAL (free_signal, (PinosListener *,
PinosLink *));
SpaList resource_list;
PinosPort *output;
SpaList output_link;
PinosPort *input;
SpaList input_link;
PINOS_SIGNAL (port_unlinked, (PinosListener *listener,
PinosLink *link,
PinosPort *port));
struct {
uint32_t in_ready;
PinosPort *input;
PinosPort *output;
SpaList input_link;
SpaList output_link;
} rt;
};
PinosLink * pinos_link_new (PinosCore *core,
PinosPort *output,
PinosPort *input,
SpaFormat **format_filter,
PinosProperties *properties);
void pinos_link_destroy (PinosLink *link);
bool pinos_link_activate (PinosLink *link);
bool pinos_link_deactivate (PinosLink *link);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_LINK_H__ */

View file

@ -1,117 +0,0 @@
/* Pinos
* Copyright (C) 2016 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 <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/eventfd.h>
#include "spa/list.h"
#include "spa/ringbuffer.h"
#include "pinos/client/log.h"
#include "pinos/server/main-loop.h"
typedef struct
{
PinosMainLoop this;
bool running;
} PinosMainLoopImpl;
/**
* pinos_main_loop_new:
*
* Create a new #PinosMainLoop.
*
* Returns: a new #PinosMainLoop
*/
PinosMainLoop *
pinos_main_loop_new (void)
{
PinosMainLoopImpl *impl;
PinosMainLoop *this;
impl = calloc (1, sizeof (PinosMainLoopImpl));
if (impl == NULL)
return NULL;
pinos_log_debug ("main-loop %p: new", impl);
this = &impl->this;
this->loop = pinos_loop_new ();
if (this->loop == NULL)
goto no_loop;
pinos_signal_init (&this->destroy_signal);
return this;
no_loop:
free (impl);
return NULL;
}
void
pinos_main_loop_destroy (PinosMainLoop *loop)
{
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
pinos_log_debug ("main-loop %p: destroy", impl);
pinos_signal_emit (&loop->destroy_signal, loop);
pinos_loop_destroy (loop->loop);
free (impl);
}
/**
* pinos_main_loop_quit:
* @loop: a #PinosMainLoop
*
* Stop the running @loop.
*/
void
pinos_main_loop_quit (PinosMainLoop *loop)
{
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
pinos_log_debug ("main-loop %p: quit", impl);
impl->running = false;
}
/**
* pinos_main_loop_run:
* @loop: a #PinosMainLoop
*
* Start running @loop. This function blocks until pinos_main_loop_quit()
* has been called.
*/
void
pinos_main_loop_run (PinosMainLoop *loop)
{
PinosMainLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosMainLoopImpl, this);
pinos_log_debug ("main-loop %p: run", impl);
impl->running = true;
pinos_loop_enter (loop->loop);
while (impl->running) {
pinos_loop_iterate (loop->loop, -1);
}
pinos_loop_leave (loop->loop);
}

View file

@ -1,139 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_NODE_H__
#define __PINOS_NODE_H__
#ifdef __cplusplus
extern "C" {
#endif
#define PINOS_TYPE__Node "Pinos:Object:Node"
#define PINOS_TYPE_NODE_BASE PINOS_TYPE__Node ":"
typedef struct _PinosNode PinosNode;
#include <spa/clock.h>
#include <spa/node.h>
#include <pinos/client/mem.h>
#include <pinos/client/transport.h>
#include <pinos/server/core.h>
#include <pinos/server/port.h>
#include <pinos/server/link.h>
#include <pinos/server/client.h>
#include <pinos/server/data-loop.h>
/**
* PinosNode:
*
* Pinos node class.
*/
struct _PinosNode {
PinosCore *core;
SpaList link;
PinosGlobal *global;
PinosClient *owner;
char *name;
PinosProperties *properties;
PinosNodeState state;
char *error;
PINOS_SIGNAL (state_request, (PinosListener *listener,
PinosNode *object,
PinosNodeState state));
PINOS_SIGNAL (state_changed, (PinosListener *listener,
PinosNode *object,
PinosNodeState old,
PinosNodeState state));
SpaHandle *handle;
SpaNode *node;
bool live;
SpaClock *clock;
SpaList resource_list;
PINOS_SIGNAL (initialized, (PinosListener *listener,
PinosNode *object));
uint32_t max_input_ports;
uint32_t n_input_ports;
SpaList input_ports;
PinosPort **input_port_map;
uint32_t n_used_input_links;
uint32_t max_output_ports;
uint32_t n_output_ports;
SpaList output_ports;
PinosPort **output_port_map;
uint32_t n_used_output_links;
PINOS_SIGNAL (port_added, (PinosListener *listener,
PinosNode *node,
PinosPort *port));
PINOS_SIGNAL (port_removed, (PinosListener *listener,
PinosNode *node,
PinosPort *port));
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosNode *object));
PINOS_SIGNAL (free_signal, (PinosListener *listener,
PinosNode *object));
PINOS_SIGNAL (async_complete, (PinosListener *listener,
PinosNode *node,
uint32_t seq,
SpaResult res));
PinosDataLoop *data_loop;
PINOS_SIGNAL (loop_changed, (PinosListener *listener,
PinosNode *object));
};
PinosNode * pinos_node_new (PinosCore *core,
PinosClient *owner,
const char *name,
bool async,
SpaNode *node,
SpaClock *clock,
PinosProperties *properties);
void pinos_node_destroy (PinosNode *node);
void pinos_node_set_data_loop (PinosNode *node,
PinosDataLoop *loop);
PinosPort * pinos_node_get_free_port (PinosNode *node,
PinosDirection direction);
SpaResult pinos_node_set_state (PinosNode *node,
PinosNodeState state);
void pinos_node_update_state (PinosNode *node,
PinosNodeState state,
char *error);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_NODE_H__ */

View file

@ -1,94 +0,0 @@
/* Pinos
* Copyright (C) 2015 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.
*/
#ifndef __PINOS_PORT_H__
#define __PINOS_PORT_H__
#ifdef __cplusplus
extern "C" {
#endif
#define PINOS_TYPE__Port "Pinos:Object:Port"
#define PINOS_TYPE_PORT_BASE PINOS_TYPE__Port ":"
typedef struct _PinosPort PinosPort;
#include <spa/node.h>
#include <pinos/client/introspect.h>
#include <pinos/client/mem.h>
#include <pinos/server/core.h>
#include <pinos/server/link.h>
typedef enum {
PINOS_PORT_STATE_ERROR = -1,
PINOS_PORT_STATE_INIT = 0,
PINOS_PORT_STATE_CONFIGURE = 1,
PINOS_PORT_STATE_READY = 2,
PINOS_PORT_STATE_PAUSED = 3,
PINOS_PORT_STATE_STREAMING = 4,
} PinosPortState;
struct _PinosPort {
SpaList link;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener, PinosPort *));
PinosNode *node;
PinosDirection direction;
uint32_t port_id;
PinosPortState state;
SpaPortIO io;
bool allocated;
PinosMemblock buffer_mem;
SpaBuffer **buffers;
uint32_t n_buffers;
SpaList links;
struct {
SpaList links;
} rt;
};
PinosPort * pinos_port_new (PinosNode *node,
PinosDirection direction,
uint32_t port_id);
void pinos_port_destroy (PinosPort *port);
PinosLink * pinos_port_link (PinosPort *output_port,
PinosPort *input_port,
SpaFormat **format_filter,
PinosProperties *properties,
char **error);
SpaResult pinos_port_unlink (PinosPort *port,
PinosLink *link);
SpaResult pinos_port_pause_rt (PinosPort *port);
SpaResult pinos_port_clear_buffers (PinosPort *port);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_PORT_H__ */

View file

@ -1,88 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <string.h>
#include "pinos/client/interfaces.h"
#include "pinos/server/resource.h"
typedef struct {
PinosResource this;
} PinosResourceImpl;
PinosResource *
pinos_resource_new (PinosClient *client,
uint32_t id,
uint32_t type,
void *object,
PinosDestroy destroy)
{
PinosResourceImpl *impl;
PinosResource *this;
impl = calloc (1, sizeof (PinosResourceImpl));
if (impl == NULL)
return NULL;
this = &impl->this;
this->core = client->core;
this->client = client;
this->type = type;
this->object = object;
this->destroy = destroy;
pinos_signal_init (&this->destroy_signal);
if (id == SPA_ID_INVALID) {
this->id = pinos_map_insert_new (&client->objects, this);
} else if (!pinos_map_insert_at (&client->objects, id, this))
goto in_use;
this->id = id;
pinos_log_debug ("resource %p: new for client %p id %u", this, client, this->id);
pinos_signal_emit (&client->resource_added, client, this);
return this;
in_use:
pinos_log_debug ("resource %p: id %u in use for client %p", this, id, client);
free (impl);
return NULL;
}
void
pinos_resource_destroy (PinosResource *resource)
{
PinosClient *client = resource->client;
pinos_log_trace ("resource %p: destroy %u", resource, resource->id);
pinos_signal_emit (&resource->destroy_signal, resource);
pinos_map_insert_at (&client->objects, resource->id, NULL);
pinos_signal_emit (&client->resource_removed, client, resource);
if (resource->destroy)
resource->destroy (resource);
if (client->core_resource)
pinos_core_notify_remove_id (client->core_resource, resource->id);
free (resource);
}

View file

@ -1,112 +0,0 @@
/* Pinos
* Copyright (C) 2015 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 <string.h>
#include <gio/gio.h>
#include <client/pinos.h>
#define ANY_CAPS "ANY"
static GMainLoop *loop;
static void
on_stream_notify (GObject *gobject,
GParamSpec *pspec,
gpointer user_data)
{
PinosStreamState state;
PinosStream *s = user_data;
g_object_get (gobject, "state", &state, NULL);
g_print ("got stream state %d\n", state);
switch (state) {
case PINOS_STREAM_STATE_ERROR:
g_main_loop_quit (loop);
break;
case PINOS_STREAM_STATE_READY:
pinos_stream_start (s);
break;
case PINOS_STREAM_STATE_STREAMING:
break;
default:
break;
}
}
static void
on_state_notify (GObject *gobject,
GParamSpec *pspec,
gpointer user_data)
{
PinosContextState state;
PinosContext *c = user_data;
g_object_get (gobject, "state", &state, NULL);
g_print ("got context state %d\n", state);
switch (state) {
case PINOS_CONTEXT_STATE_ERROR:
g_main_loop_quit (loop);
break;
case PINOS_CONTEXT_STATE_CONNECTED:
{
PinosStream *stream;
GPtrArray *possible;
stream = pinos_stream_new (c, "test", NULL);
g_signal_connect (stream, "notify::state", (GCallback) on_stream_notify, stream);
possible = NULL;
pinos_stream_connect (stream,
PINOS_DIRECTION_OUTPUT,
PINOS_STREAM_MODE_BUFFER,
NULL,
0,
possible);
break;
}
default:
break;
}
}
gint
main (gint argc, gchar *argv[])
{
PinosContext *c;
pinos_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
c = pinos_context_new (NULL, "test-client", NULL);
g_signal_connect (c, "notify::state", (GCallback) on_state_notify, c);
pinos_context_connect(c, PINOS_CONTEXT_FLAGS_NONE);
g_main_loop_run (loop);
g_object_unref (c);
return 0;
}

View file

@ -1,5 +0,0 @@
executable('pinos-monitor',
'pinos-monitor.c',
install: true,
dependencies : [pinos_dep],
)

View file

@ -11,18 +11,18 @@
# where/how to apply multilib hacks
%global multilib_archs x86_64 %{ix86} ppc64 ppc s390x s390 sparc64 sparcv9 ppc64le
Name: pinos
Name: pipewire
Summary: Media Sharing Server
Version: 0.1
Release: 2%{?snap:.%{snap}git%{shortcommit}}%{?dist}
License: LGPLv2+
URL: http://www.freedesktop.org/wiki/Software/Pinos
URL: http://www.freedesktop.org/wiki/Software/PipeWire
%if 0%{?gitrel}
# git clone git://anongit.freedesktop.org/gstreamer/pinos
# cd pinos; git reset --hard %{gitcommit}; ./autogen.sh; make; make distcheck
Source0: pinos-%{version}-%{gitrel}-g%{shortcommit}.tar.xz
# git clone git://anongit.freedesktop.org/gstreamer/pipewire
# cd pipewire; git reset --hard %{gitcommit}; ./autogen.sh; make; make distcheck
Source0: pipewire-%{version}-%{gitrel}-g%{shortcommit}.tar.xz
%else
Source0: http://freedesktop.org/software/pinos/releases/pinos-%{version}.tar.xz
Source0: http://freedesktop.org/software/pipewire/releases/pipewire-%{version}.tar.xz
%endif
## upstream patches
@ -51,32 +51,32 @@ Requires: systemd >= 184
Requires: rtkit
%description
Pinos is a multimedia server for Linux and other Unix like operating
PipeWire is a multimedia server for Linux and other Unix like operating
systems.
%package libs
Summary: Libraries for Pinos clients
Summary: Libraries for PipeWire clients
License: LGPLv2+
%description libs
This package contains the runtime libraries for any application that wishes
to interface with a Pinos media server.
to interface with a PipeWire media server.
%package libs-devel
Summary: Headers and libraries for Pinos client development
Summary: Headers and libraries for PipeWire client development
License: LGPLv2+
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
%description libs-devel
Headers and libraries for developing applications that can communicate with
a Pinos media server.
a PipeWire media server.
%package utils
Summary: Pinos media server utilities
Summary: PipeWire media server utilities
License: LGPLv2+
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
%description utils
This package contains command line utilities for the Pinos media server.
This package contains command line utilities for the PipeWire media server.
%prep
%setup -q -T -b0 -n %{name}-%{version}%{?gitrel:-%{gitrel}-g%{shortcommit}}
@ -97,9 +97,9 @@ sed -i -e 's|"/lib /usr/lib|"/%{_lib} %{_libdir}|' configure
--disable-silent-rules \
--disable-static \
--disable-rpath \
--with-system-user=pinos \
--with-system-group=pinos \
--with-access-group=pinos-access \
--with-system-user=pipewire \
--with-system-group=pipewire \
--with-access-group=pipewire-access \
--disable-systemd-daemon \
--enable-tests
@ -123,9 +123,9 @@ make check \
%pre
getent group pinos >/dev/null || groupadd -r pinos
getent passwd pinos >/dev/null || \
useradd -r -g pinos -d /var/run/pinos -s /sbin/nologin -c "Pinos System Daemon" pinos
getent group pipewire >/dev/null || groupadd -r pipewire
getent passwd pipewire >/dev/null || \
useradd -r -g pipewire -d /var/run/pipewire -s /sbin/nologin -c "PipeWire System Daemon" pipewire
exit 0
%post -p /sbin/ldconfig
@ -134,29 +134,29 @@ exit 0
%files
%license LICENSE GPL LGPL
%doc README
%{_sysconfdir}/xdg/autostart/pinos.desktop
%{_sysconfdir}/xdg/autostart/pipewire.desktop
## already owned by -libs, see also https://bugzilla.redhat.com/show_bug.cgi?id=909690
#dir %{_sysconfdir}/pinos/
%{_sysconfdir}/dbus-1/system.d/pinos-system.conf
%{_bindir}/pinos
%{_libdir}/libpinos-%{majorminor}.so
%{_libdir}/libpinoscore-%{majorminor}.so
%{_libdir}/gstreamer-1.0/libgstpinos.*
%{_mandir}/man1/pinos.1*
#dir %{_sysconfdir}/pipewire/
%{_sysconfdir}/dbus-1/system.d/pipewire-system.conf
%{_bindir}/pipewire
%{_libdir}/libpipewire-%{majorminor}.so
%{_libdir}/libpipewirecore-%{majorminor}.so
%{_libdir}/gstreamer-1.0/libgstpipewire.*
%{_mandir}/man1/pipewire.1*
%files libs
%files libs
%license LICENSE GPL LGPL
%doc README
#%dir %{_sysconfdir}/pinos/
#%dir %{_libdir}/pinos/
#%dir %{_sysconfdir}/pipewire/
#%dir %{_libdir}/pipewire/
%files libs-devel
%{_includedir}/pinos/
%{_libdir}/pkgconfig/libpinos*.pc
%{_includedir}/pipewire/
%{_libdir}/pkgconfig/libpipewire*.pc
%files utils
%{_bindir}/pinos-monitor
%{_mandir}/man1/pinos-monitor.1*
%{_bindir}/pipewire-monitor
%{_mandir}/man1/pipewire-monitor.1*
%changelog
* Wed Sep 9 2015 Wim Taymans <wtaymans@redhat.com> - 0.1.0-2

0
pipewire/.gitignore vendored Normal file
View file

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,41 +17,39 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __PINOS_ARRAY_H__
#define __PINOS_ARRAY_H__
#ifndef __PIPEWIRE_ARRAY_H__
#define __PIPEWIRE_ARRAY_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosArray PinosArray;
#include <spa/defs.h>
struct _PinosArray {
struct pw_array {
void *data;
size_t size;
size_t alloc;
size_t extend;
};
#define PINOS_ARRAY_INIT(extend) { NULL, 0, 0, extend }
#define PW_ARRAY_INIT(extend) { NULL, 0, 0, extend }
#define pinos_array_get_len_s(a,s) ((a)->size / (s))
#define pinos_array_get_unchecked_s(a,idx,s,t) SPA_MEMBER ((a)->data,(idx)*(s),t)
#define pinos_array_check_index_s(a,idx,s) ((idx) < pinos_array_get_len(a,s))
#define pw_array_get_len_s(a,s) ((a)->size / (s))
#define pw_array_get_unchecked_s(a,idx,s,t) SPA_MEMBER ((a)->data,(idx)*(s),t)
#define pw_array_check_index_s(a,idx,s) ((idx) < pw_array_get_len(a,s))
#define pinos_array_get_len(a,t) pinos_array_get_len_s(a,sizeof(t))
#define pinos_array_get_unchecked(a,idx,t) pinos_array_get_unchecked_s(a,idx,sizeof(t),t)
#define pinos_array_check_index(a,idx,t) pinos_array_check_index_s(a,idx,sizeof(t))
#define pw_array_get_len(a,t) pw_array_get_len_s(a,sizeof(t))
#define pw_array_get_unchecked(a,idx,t) pw_array_get_unchecked_s(a,idx,sizeof(t),t)
#define pw_array_check_index(a,idx,t) pw_array_check_index_s(a,idx,sizeof(t))
#define pinos_array_for_each(pos, array) \
#define pw_array_for_each(pos, array) \
for (pos = (array)->data; \
(const uint8_t *) pos < ((const uint8_t *) (array)->data + (array)->size); \
(pos)++)
static inline void
pinos_array_init (PinosArray *arr, size_t extend)
pw_array_init (struct pw_array *arr, size_t extend)
{
arr->data = NULL;
arr->size = arr->alloc = 0;
@ -59,14 +57,14 @@ pinos_array_init (PinosArray *arr, size_t extend)
}
static inline void
pinos_array_clear (PinosArray *arr)
pw_array_clear (struct pw_array *arr)
{
free (arr->data);
}
static inline bool
pinos_array_ensure_size (PinosArray *arr,
size_t size)
pw_array_ensure_size (struct pw_array *arr,
size_t size)
{
size_t alloc, need;
@ -87,12 +85,12 @@ pinos_array_ensure_size (PinosArray *arr,
}
static inline void *
pinos_array_add (PinosArray *arr,
size_t size)
pw_array_add (struct pw_array *arr,
size_t size)
{
void *p;
if (!pinos_array_ensure_size (arr, size))
if (!pw_array_ensure_size (arr, size))
return NULL;
p = arr->data + arr->size;
@ -102,8 +100,8 @@ pinos_array_add (PinosArray *arr,
}
static inline void *
pinos_array_add_fixed (PinosArray *arr,
size_t size)
pw_array_add_fixed (struct pw_array *arr,
size_t size)
{
void *p;
@ -116,11 +114,11 @@ pinos_array_add_fixed (PinosArray *arr,
return p;
}
#define pinos_array_add_ptr(a,p) \
*((void**) pinos_array_add (a, sizeof (void*))) = (p)
#define pw_array_add_ptr(a,p) \
*((void**) pw_array_add (a, sizeof (void*))) = (p)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __PINOS_ARRAY_H__ */
#endif /* __PIPEWIRE_ARRAY_H__ */

View file

@ -1,4 +1,4 @@
/* Simple Plugin API
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -31,7 +31,7 @@
#define MAX_BUFFER_SIZE 4096
#define MAX_FDS 28
typedef struct {
struct buffer {
uint8_t *buffer_data;
size_t buffer_size;
size_t buffer_maxsize;
@ -43,19 +43,19 @@ typedef struct {
size_t size;
bool update;
} ConnectionBuffer;
};
typedef struct {
PinosConnection this;
struct pw_connection_impl {
struct pw_connection this;
ConnectionBuffer in, out;
} PinosConnectionImpl;
struct buffer in, out;
};
int
pinos_connection_get_fd (PinosConnection *conn,
uint32_t index)
pw_connection_get_fd (struct pw_connection *conn,
uint32_t index)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
if (index < 0 || index >= impl->in.n_fds)
return -1;
@ -64,10 +64,10 @@ pinos_connection_get_fd (PinosConnection *conn,
}
uint32_t
pinos_connection_add_fd (PinosConnection *conn,
int fd)
pw_connection_add_fd (struct pw_connection *conn,
int fd)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
uint32_t index, i;
for (i = 0; i < impl->out.n_fds; i++) {
@ -77,7 +77,7 @@ pinos_connection_add_fd (PinosConnection *conn,
index = impl->out.n_fds;
if (index >= MAX_FDS) {
pinos_log_error ("connection %p: too many fds", conn);
pw_log_error ("connection %p: too many fds", conn);
return -1;
}
@ -88,18 +88,20 @@ pinos_connection_add_fd (PinosConnection *conn,
}
static void *
connection_ensure_size (PinosConnection *conn, ConnectionBuffer *buf, size_t size)
connection_ensure_size (struct pw_connection *conn, struct buffer *buf, size_t size)
{
if (buf->buffer_size + size > buf->buffer_maxsize) {
buf->buffer_maxsize = SPA_ROUND_UP_N (buf->buffer_size + size, MAX_BUFFER_SIZE);
pinos_log_warn ("connection %p: resize buffer to %zd %zd %zd", conn, buf->buffer_size, size, buf->buffer_maxsize);
buf->buffer_data = realloc (buf->buffer_data, buf->buffer_maxsize);
pw_log_warn ("connection %p: resize buffer to %zd %zd %zd",
conn, buf->buffer_size, size, buf->buffer_maxsize);
}
return (uint8_t *) buf->buffer_data + buf->buffer_size;
}
static bool
refill_buffer (PinosConnection *conn, ConnectionBuffer *buf)
refill_buffer (struct pw_connection *conn, struct buffer *buf)
{
ssize_t len;
struct cmsghdr *cmsg;
@ -136,20 +138,20 @@ refill_buffer (PinosConnection *conn, ConnectionBuffer *buf)
buf->n_fds = (cmsg->cmsg_len - ((char *)CMSG_DATA (cmsg) - (char *)cmsg)) / sizeof (int);
memcpy (buf->fds, CMSG_DATA (cmsg), buf->n_fds * sizeof (int));
}
pinos_log_trace ("connection %p: %d read %zd bytes and %d fds", conn, conn->fd, len, buf->n_fds);
pw_log_trace ("connection %p: %d read %zd bytes and %d fds", conn, conn->fd, len, buf->n_fds);
return true;
/* ERRORS */
recv_error:
{
pinos_log_error ("could not recvmsg on fd %d: %s", conn->fd, strerror (errno));
pw_log_error ("could not recvmsg on fd %d: %s", conn->fd, strerror (errno));
return false;
}
}
static void
clear_buffer (ConnectionBuffer *buf)
clear_buffer (struct buffer *buf)
{
buf->n_fds = 0;
buf->offset = 0;
@ -157,23 +159,23 @@ clear_buffer (ConnectionBuffer *buf)
buf->buffer_size = 0;
}
PinosConnection *
pinos_connection_new (int fd)
struct pw_connection *
pw_connection_new (int fd)
{
PinosConnectionImpl *impl;
PinosConnection *this;
struct pw_connection_impl *impl;
struct pw_connection *this;
impl = calloc (1, sizeof (PinosConnectionImpl));
impl = calloc (1, sizeof (struct pw_connection_impl));
if (impl == NULL)
return NULL;
this = &impl->this;
pinos_log_debug ("connection %p: new", this);
pw_log_debug ("connection %p: new", this);
this->fd = fd;
pinos_signal_init (&this->need_flush);
pinos_signal_init (&this->destroy_signal);
pw_signal_init (&this->need_flush);
pw_signal_init (&this->destroy_signal);
impl->out.buffer_data = malloc (MAX_BUFFER_SIZE);
impl->out.buffer_maxsize = MAX_BUFFER_SIZE;
@ -194,13 +196,13 @@ no_mem:
}
void
pinos_connection_destroy (PinosConnection *conn)
pw_connection_destroy (struct pw_connection *conn)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
pinos_log_debug ("connection %p: destroy", conn);
pw_log_debug ("connection %p: destroy", conn);
pinos_signal_emit (&conn->destroy_signal, conn);
pw_signal_emit (&conn->destroy_signal, conn);
free (impl->out.buffer_data);
free (impl->in.buffer_data);
@ -208,24 +210,24 @@ pinos_connection_destroy (PinosConnection *conn)
}
/**
* pinos_connection_has_next:
* @iter: a #PinosConnection
* pw_connection_has_next:
* @iter: a connection
*
* Move to the next packet in @conn.
*
* Returns: %true if more packets are available.
*/
bool
pinos_connection_get_next (PinosConnection *conn,
pw_connection_get_next (struct pw_connection *conn,
uint8_t *opcode,
uint32_t *dest_id,
void **dt,
uint32_t *sz)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
size_t len, size;
uint8_t *data;
ConnectionBuffer *buf;
struct buffer *buf;
uint32_t *p;
buf = &impl->in;
@ -284,26 +286,26 @@ again:
}
void *
pinos_connection_begin_write (PinosConnection *conn,
pw_connection_begin_write (struct pw_connection *conn,
uint32_t size)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
uint32_t *p;
ConnectionBuffer *buf = &impl->out;
struct buffer *buf = &impl->out;
/* 4 for dest_id, 1 for opcode, 3 for size and size for payload */
p = connection_ensure_size (conn, buf, 8 + size);
return p + 2;
}
void
pinos_connection_end_write (PinosConnection *conn,
pw_connection_end_write (struct pw_connection *conn,
uint32_t dest_id,
uint8_t opcode,
uint32_t size)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
uint32_t *p;
ConnectionBuffer *buf = &impl->out;
struct buffer *buf = &impl->out;
p = connection_ensure_size (conn, buf, 8 + size);
*p++ = dest_id;
@ -313,20 +315,20 @@ pinos_connection_end_write (PinosConnection *conn,
// spa_debug_pod (p);
pinos_signal_emit (&conn->need_flush, conn);
pw_signal_emit (&conn->need_flush, conn);
}
bool
pinos_connection_flush (PinosConnection *conn)
pw_connection_flush (struct pw_connection *conn)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
ssize_t len;
struct msghdr msg = {0};
struct iovec iov[1];
struct cmsghdr *cmsg;
char cmsgbuf[CMSG_SPACE (MAX_FDS * sizeof (int))];
int *cm, i, fds_len;
ConnectionBuffer *buf;
struct buffer *buf;
buf = &impl->out;
@ -366,7 +368,7 @@ pinos_connection_flush (PinosConnection *conn)
}
break;
}
pinos_log_trace ("connection %p: %d written %zd bytes and %u fds", conn, conn->fd, len, buf->n_fds);
pw_log_trace ("connection %p: %d written %zd bytes and %u fds", conn, conn->fd, len, buf->n_fds);
buf->buffer_size -= len;
buf->n_fds = 0;
@ -376,15 +378,15 @@ pinos_connection_flush (PinosConnection *conn)
/* ERRORS */
send_error:
{
pinos_log_error ("could not sendmsg: %s", strerror (errno));
pw_log_error ("could not sendmsg: %s", strerror (errno));
return false;
}
}
bool
pinos_connection_clear (PinosConnection *conn)
pw_connection_clear (struct pw_connection *conn)
{
PinosConnectionImpl *impl = SPA_CONTAINER_OF (conn, PinosConnectionImpl, this);
struct pw_connection_impl *impl = SPA_CONTAINER_OF (conn, struct pw_connection_impl, this);
clear_buffer (&impl->out);
clear_buffer (&impl->in);

View file

@ -0,0 +1,67 @@
/* PipeWire
* Copyright (C) 2016 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.
*/
#ifndef __PIPEWIRE_CONNECTION_H__
#define __PIPEWIRE_CONNECTION_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/defs.h>
#include <pipewire/client/sig.h>
struct pw_connection {
int fd;
PW_SIGNAL (need_flush, (struct pw_listener *listener,
struct pw_connection *conn));
PW_SIGNAL (destroy_signal, (struct pw_listener *listener,
struct pw_connection *conn));
};
struct pw_connection * pw_connection_new (int fd);
void pw_connection_destroy (struct pw_connection *conn);
uint32_t pw_connection_add_fd (struct pw_connection *conn,
int fd);
int pw_connection_get_fd (struct pw_connection *conn,
uint32_t index);
bool pw_connection_get_next (struct pw_connection *conn,
uint8_t *opcode,
uint32_t *dest_id,
void **data,
uint32_t *size);
void * pw_connection_begin_write (struct pw_connection *conn,
uint32_t size);
void pw_connection_end_write (struct pw_connection *conn,
uint32_t dest_id,
uint8_t opcode,
uint32_t size);
bool pw_connection_flush (struct pw_connection *conn);
bool pw_connection_clear (struct pw_connection *conn);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __PIPEWIRE_CONNECTION_H__ */

878
pipewire/client/context.c Normal file
View file

@ -0,0 +1,878 @@
/* PipeWire
* Copyright (C) 2015 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 <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include "pipewire/client/pipewire.h"
#include "pipewire/client/context.h"
#include "pipewire/client/introspect.h"
#include "pipewire/client/protocol-native.h"
#include "pipewire/client/connection.h"
#include "pipewire/client/subscribe.h"
struct context {
struct pw_context this;
bool no_proxy;
int fd;
struct pw_connection *connection;
SpaSource *source;
bool disconnecting;
struct pw_listener need_flush;
SpaSource *flush_event;
};
/**
* pw_context_state_as_string:
* @state: a #enum pw_context_state
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *
pw_context_state_as_string (enum pw_context_state state)
{
switch (state) {
case PW_CONTEXT_STATE_ERROR:
return "error";
case PW_CONTEXT_STATE_UNCONNECTED:
return "unconnected";
case PW_CONTEXT_STATE_CONNECTING:
return "connecting";
case PW_CONTEXT_STATE_CONNECTED:
return "connected";
}
return "invalid-state";
}
static void
context_set_state (struct pw_context *context,
enum pw_context_state state,
const char *fmt,
...)
{
if (context->state != state) {
if (context->error)
free (context->error);
if (fmt) {
va_list varargs;
va_start (varargs, fmt);
vasprintf (&context->error, fmt, varargs);
va_end (varargs);
} else {
context->error = NULL;
}
pw_log_debug ("context %p: update state from %s -> %s (%s)", context,
pw_context_state_as_string (context->state),
pw_context_state_as_string (state),
context->error);
context->state = state;
pw_signal_emit (&context->state_changed, context);
}
}
static void
core_event_info (void *object,
struct pw_core_info *info)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
enum pw_subscription_event event;
pw_log_debug ("got core info");
if (proxy->user_data == NULL)
event = PW_SUBSCRIPTION_EVENT_NEW;
else
event = PW_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pw_core_info_update (proxy->user_data, info);
pw_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static void
core_event_done (void *object,
uint32_t seq)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
if (seq == 0) {
pw_core_do_sync (this->core_proxy, 1);
} else if (seq == 1) {
context_set_state (this, PW_CONTEXT_STATE_CONNECTED, NULL);
}
}
static void
core_event_error (void *object,
uint32_t id,
SpaResult res,
const char *error, ...)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
context_set_state (this, PW_CONTEXT_STATE_ERROR, error);
}
static void
core_event_remove_id (void *object,
uint32_t id)
{
struct pw_proxy *core_proxy = object;
struct pw_context *this = core_proxy->context;
struct pw_proxy *proxy;
proxy = pw_map_lookup (&this->objects, id);
if (proxy) {
pw_log_debug ("context %p: object remove %u", this, id);
pw_proxy_destroy (proxy);
}
}
static void
core_event_update_types (void *object,
uint32_t first_id,
uint32_t n_types,
const char **types)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
int i;
for (i = 0; i < n_types; i++, first_id++) {
SpaType this_id = spa_type_map_get_id (this->type.map, types[i]);
if (!pw_map_insert_at (&this->types, first_id, PW_MAP_ID_TO_PTR (this_id)))
pw_log_error ("can't add type for client");
}
}
static const struct pw_core_events core_events = {
&core_event_info,
&core_event_done,
&core_event_error,
&core_event_remove_id,
&core_event_update_types
};
static void
module_event_info (void *object,
struct pw_module_info *info)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
enum pw_subscription_event event;
pw_log_debug ("got module info");
if (proxy->user_data == NULL)
event = PW_SUBSCRIPTION_EVENT_NEW;
else
event = PW_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pw_module_info_update (proxy->user_data, info);
pw_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const struct pw_module_events module_events = {
&module_event_info,
};
static void
node_event_info (void *object,
struct pw_node_info *info)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
enum pw_subscription_event event;
pw_log_debug ("got node info");
if (proxy->user_data == NULL)
event = PW_SUBSCRIPTION_EVENT_NEW;
else
event = PW_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pw_node_info_update (proxy->user_data, info);
pw_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const struct pw_node_events node_events = {
&node_event_info
};
static void
client_event_info (void *object,
struct pw_client_info *info)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
enum pw_subscription_event event;
pw_log_debug ("got client info");
if (proxy->user_data == NULL)
event = PW_SUBSCRIPTION_EVENT_NEW;
else
event = PW_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pw_client_info_update (proxy->user_data, info);
pw_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const struct pw_client_events client_events = {
&client_event_info
};
static void
link_event_info (void *object,
struct pw_link_info *info)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
enum pw_subscription_event event;
pw_log_debug ("got link info");
if (proxy->user_data == NULL)
event = PW_SUBSCRIPTION_EVENT_NEW;
else
event = PW_SUBSCRIPTION_EVENT_CHANGE;
proxy->user_data = pw_link_info_update (proxy->user_data, info);
pw_signal_emit (&this->subscription,
this,
event,
proxy->type,
proxy->id);
}
static const struct pw_link_events link_events = {
&link_event_info
};
static void
registry_event_global (void *object,
uint32_t id,
const char *type)
{
struct pw_proxy *registry_proxy = object;
struct pw_context *this = registry_proxy->context;
struct context *impl = SPA_CONTAINER_OF (this, struct context, this);
struct pw_proxy *proxy = NULL;
if (impl->no_proxy)
return;
pw_log_debug ("got global %u %s", id, type);
if (!strcmp (type, PIPEWIRE_TYPE__Node)) {
proxy = pw_proxy_new (this,
SPA_ID_INVALID,
this->type.node);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &node_events;
} else if (!strcmp (type, PIPEWIRE_TYPE__Module)) {
proxy = pw_proxy_new (this,
SPA_ID_INVALID,
this->type.module);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &module_events;
} else if (!strcmp (type, PIPEWIRE_TYPE__Client)) {
proxy = pw_proxy_new (this,
SPA_ID_INVALID,
this->type.client);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &client_events;
} else if (!strcmp (type, PIPEWIRE_TYPE__Link)) {
proxy = pw_proxy_new (this,
SPA_ID_INVALID,
this->type.link);
if (proxy == NULL)
goto no_mem;
proxy->implementation = &link_events;
}
if (proxy) {
pw_registry_do_bind (registry_proxy, id, proxy->id);
}
return;
no_mem:
pw_log_error ("context %p: failed to create proxy", this);
return;
}
static void
registry_event_global_remove (void *object,
uint32_t id)
{
struct pw_proxy *proxy = object;
struct pw_context *this = proxy->context;
pw_log_debug ("got global remove %u", id);
pw_signal_emit (&this->subscription,
this,
PW_SUBSCRIPTION_EVENT_REMOVE,
SPA_ID_INVALID,
id);
}
static const struct pw_registry_events registry_events = {
&registry_event_global,
&registry_event_global_remove
};
typedef bool (*demarshal_func_t) (void *object, void *data, size_t size);
static void
do_flush_event (SpaLoopUtils *utils,
SpaSource *source,
void *data)
{
struct context *impl = data;
if (impl->connection)
if (!pw_connection_flush (impl->connection))
pw_context_disconnect (&impl->this);
}
static void
on_need_flush (struct pw_listener *listener,
struct pw_connection *connection)
{
struct context *impl = SPA_CONTAINER_OF (listener, struct context, need_flush);
struct pw_context *this = &impl->this;
pw_loop_signal_event (this->loop, impl->flush_event);
}
static void
on_context_data (SpaLoopUtils *utils,
SpaSource *source,
int fd,
SpaIO mask,
void *data)
{
struct context *impl = data;
struct pw_context *this = &impl->this;
struct pw_connection *conn = impl->connection;
if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
context_set_state (this,
PW_CONTEXT_STATE_ERROR,
"connection closed");
return;
}
if (mask & SPA_IO_IN) {
uint8_t opcode;
uint32_t id;
uint32_t size;
void *message;
while (!impl->disconnecting
&& pw_connection_get_next (conn, &opcode, &id, &message, &size)) {
struct pw_proxy *proxy;
const demarshal_func_t *demarshal;
pw_log_trace ("context %p: got message %d from %u", this, opcode, id);
proxy = pw_map_lookup (&this->objects, id);
if (proxy == NULL) {
pw_log_error ("context %p: could not find proxy %u", this, id);
continue;
}
if (opcode >= proxy->iface->n_events) {
pw_log_error ("context %p: invalid method %u for %u", this, opcode, id);
continue;
}
demarshal = proxy->iface->events;
if (demarshal[opcode]) {
if (!demarshal[opcode] (proxy, message, size))
pw_log_error ("context %p: invalid message received %u for %u", this, opcode, id);
} else
pw_log_error ("context %p: function %d not implemented on %u", this, opcode, id);
}
}
}
/**
* pw_context_new:
* @context: a #GMainContext to run in
* @name: an application name
* @properties: (transfer full): optional properties
*
* Make a new unconnected #struct pw_context
*
* Returns: a new unconnected #struct pw_context
*/
struct pw_context *
pw_context_new (struct pw_loop *loop,
const char *name,
struct pw_properties *properties)
{
struct context *impl;
struct pw_context *this;
impl = calloc (1, sizeof (struct context));
if (impl == NULL)
return NULL;
impl->fd = -1;
this = &impl->this;
pw_log_debug ("context %p: new", impl);
this->name = strdup (name);
if (properties == NULL)
properties = pw_properties_new ("application.name", name, NULL);
if (properties == NULL)
goto no_mem;
pw_fill_context_properties (properties);
this->properties = properties;
pw_type_init (&this->type);
this->loop = loop;
impl->flush_event = pw_loop_add_event (loop, do_flush_event, impl);
this->state = PW_CONTEXT_STATE_UNCONNECTED;
pw_map_init (&this->objects, 64, 32);
pw_map_init (&this->types, 64, 32);
spa_list_init (&this->stream_list);
spa_list_init (&this->global_list);
spa_list_init (&this->proxy_list);
pw_signal_init (&this->state_changed);
pw_signal_init (&this->subscription);
pw_signal_init (&this->destroy_signal);
return this;
no_mem:
free (this->name);
free (impl);
return NULL;
}
void
pw_context_destroy (struct pw_context *context)
{
struct context *impl = SPA_CONTAINER_OF (context, struct context, this);
struct pw_stream *stream, *t1;
struct pw_proxy *proxy, *t2;
pw_log_debug ("context %p: destroy", context);
pw_signal_emit (&context->destroy_signal, context);
pw_loop_destroy_source (impl->this.loop, impl->flush_event);
if (context->state != PW_CONTEXT_STATE_UNCONNECTED)
pw_context_disconnect (context);
spa_list_for_each_safe (stream, t1, &context->stream_list, link)
pw_stream_destroy (stream);
spa_list_for_each_safe (proxy, t2, &context->proxy_list, link)
pw_proxy_destroy (proxy);
pw_map_clear (&context->objects);
free (context->name);
if (context->properties)
pw_properties_free (context->properties);
free (context->error);
free (impl);
}
/**
* pw_context_connect:
* @context: a #struct pw_context
*
* Connect to the daemon
*
* Returns: %TRUE on success.
*/
bool
pw_context_connect (struct pw_context *context,
enum pw_context_flags flags)
{
struct sockaddr_un addr;
socklen_t size;
const char *runtime_dir, *name = NULL;
int name_size, fd;
if ((runtime_dir = getenv ("XDG_RUNTIME_DIR")) == NULL) {
context_set_state (context,
PW_CONTEXT_STATE_ERROR,
"connect failed: XDG_RUNTIME_DIR not set in the environment");
return false;
}
if (name == NULL)
name = getenv("PIPEWIRE_CORE");
if (name == NULL)
name = "pipewire-0";
if ((fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0)
return false;
memset (&addr, 0, sizeof (addr));
addr.sun_family = AF_LOCAL;
name_size = snprintf (addr.sun_path, sizeof (addr.sun_path),
"%s/%s", runtime_dir, name) + 1;
if (name_size > (int)sizeof addr.sun_path) {
pw_log_error ("socket path \"%s/%s\" plus null terminator exceeds 108 bytes",
runtime_dir, name);
goto error_close;
};
size = offsetof (struct sockaddr_un, sun_path) + name_size;
if (connect (fd, (struct sockaddr *) &addr, size) < 0) {
context_set_state (context,
PW_CONTEXT_STATE_ERROR,
"connect failed: %s", strerror (errno));
goto error_close;
}
return pw_context_connect_fd (context, flags, fd);
error_close:
close (fd);
return false;
}
/**
* pw_context_connect_fd:
* @context: a #struct pw_context
* @fd: FD of a connected PipeWire socket
*
* Connect to a daemon. @fd should already be connected to a PipeWire socket.
*
* Returns: %TRUE on success.
*/
bool
pw_context_connect_fd (struct pw_context *context,
enum pw_context_flags flags,
int fd)
{
struct context *impl = SPA_CONTAINER_OF (context, struct context, this);
context_set_state (context, PW_CONTEXT_STATE_CONNECTING, NULL);
impl->connection = pw_connection_new (fd);
if (impl->connection == NULL)
goto error_close;
context->protocol_private = impl->connection;
pw_signal_add (&impl->connection->need_flush,
&impl->need_flush,
on_need_flush);
impl->fd = fd;
impl->source = pw_loop_add_io (context->loop,
fd,
SPA_IO_IN | SPA_IO_HUP | SPA_IO_ERR,
false,
on_context_data,
impl);
context->core_proxy = pw_proxy_new (context,
0,
context->type.core);
if (context->core_proxy == NULL)
goto no_proxy;
context->core_proxy->implementation = &core_events;
pw_core_do_client_update (context->core_proxy,
&context->properties->dict);
if (!(flags & PW_CONTEXT_FLAG_NO_REGISTRY)) {
context->registry_proxy = pw_proxy_new (context,
SPA_ID_INVALID,
context->type.registry);
if (context->registry_proxy == NULL)
goto no_registry;
context->registry_proxy->implementation = &registry_events;
pw_core_do_get_registry (context->core_proxy,
context->registry_proxy->id);
}
impl->no_proxy = !!(flags & PW_CONTEXT_FLAG_NO_PROXY);
pw_core_do_sync (context->core_proxy, 0);
return true;
no_registry:
pw_proxy_destroy (context->core_proxy);
no_proxy:
pw_loop_destroy_source (context->loop, impl->source);
pw_connection_destroy (impl->connection);
error_close:
close (fd);
return false;
}
/**
* pw_context_disconnect:
* @context: a #struct pw_context
*
* Disonnect from the daemon.
*
* Returns: %TRUE on success.
*/
bool
pw_context_disconnect (struct pw_context *context)
{
struct context *impl = SPA_CONTAINER_OF (context, struct context, this);
impl->disconnecting = true;
if (impl->source)
pw_loop_destroy_source (context->loop, impl->source);
impl->source = NULL;
if (context->registry_proxy)
pw_proxy_destroy (context->registry_proxy);
context->registry_proxy = NULL;
if (context->core_proxy)
pw_proxy_destroy (context->core_proxy);
context->core_proxy = NULL;
if (impl->connection)
pw_connection_destroy (impl->connection);
impl->connection = NULL;
context->protocol_private = NULL;
if (impl->fd != -1)
close (impl->fd);
impl->fd = -1;
context_set_state (context, PW_CONTEXT_STATE_UNCONNECTED, NULL);
return true;
}
void
pw_context_get_core_info (struct pw_context *context,
pw_core_info_cb_t cb,
void *user_data)
{
struct pw_proxy *proxy;
proxy = pw_map_lookup (&context->objects, 0);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.core && proxy->user_data) {
struct pw_core_info *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
typedef void (*list_func_t) (struct pw_context *, SpaResult, void *, void *);
static void
do_list (struct pw_context *context,
uint32_t type,
list_func_t cb,
void *user_data)
{
union pw_map_item *item;
pw_array_for_each (item, &context->objects.items) {
struct pw_proxy *proxy;
if (pw_map_item_is_free (item))
continue;
proxy = item->data;
if (proxy->type != type)
continue;
if (proxy->user_data)
cb (context, SPA_RESULT_OK, proxy->user_data, user_data);
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pw_context_list_module_info (struct pw_context *context,
pw_module_info_cb_t cb,
void *user_data)
{
do_list (context, context->type.module, (list_func_t) cb, user_data);
}
void
pw_context_get_module_info_by_id (struct pw_context *context,
uint32_t id,
pw_module_info_cb_t cb,
void *user_data)
{
struct pw_proxy *proxy;
proxy = pw_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.module && proxy->user_data) {
struct pw_module_info *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pw_context_list_client_info (struct pw_context *context,
pw_client_info_cb_t cb,
void *user_data)
{
do_list (context, context->type.client, (list_func_t) cb, user_data);
}
void
pw_context_get_client_info_by_id (struct pw_context *context,
uint32_t id,
pw_client_info_cb_t cb,
void *user_data)
{
struct pw_proxy *proxy;
proxy = pw_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.client && proxy->user_data) {
struct pw_client_info *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pw_context_list_node_info (struct pw_context *context,
pw_node_info_cb_t cb,
void *user_data)
{
do_list (context, context->type.node, (list_func_t) cb, user_data);
}
void
pw_context_get_node_info_by_id (struct pw_context *context,
uint32_t id,
pw_node_info_cb_t cb,
void *user_data)
{
struct pw_proxy *proxy;
proxy = pw_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.node && proxy->user_data) {
struct pw_node_info *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}
void
pw_context_list_link_info (struct pw_context *context,
pw_link_info_cb_t cb,
void *user_data)
{
do_list (context, context->type.link, (list_func_t) cb, user_data);
}
void
pw_context_get_link_info_by_id (struct pw_context *context,
uint32_t id,
pw_link_info_cb_t cb,
void *user_data)
{
struct pw_proxy *proxy;
proxy = pw_map_lookup (&context->objects, id);
if (proxy == NULL) {
cb (context, SPA_RESULT_INVALID_OBJECT_ID, NULL, user_data);
} else if (proxy->type == context->type.link && proxy->user_data) {
struct pw_link_info *info = proxy->user_data;
cb (context, SPA_RESULT_OK, info, user_data);
info->change_mask = 0;
}
cb (context, SPA_RESULT_ENUM_END, NULL, user_data);
}

115
pipewire/client/context.h Normal file
View file

@ -0,0 +1,115 @@
/* PipeWire
* Copyright (C) 2015 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.
*/
#ifndef __PIPEWIRE_CONTEXT_H__
#define __PIPEWIRE_CONTEXT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <pipewire/client/map.h>
#include <pipewire/client/loop.h>
#include <pipewire/client/properties.h>
#include <pipewire/client/subscribe.h>
#include <pipewire/client/proxy.h>
#include <pipewire/client/type.h>
/**
* pw_context_state:
* @PW_CONTEXT_STATE_ERROR: context is in error
* @PW_CONTEXT_STATE_UNCONNECTED: not connected
* @PW_CONTEXT_STATE_CONNECTING: connecting to daemon
* @PW_CONTEXT_STATE_CONNECTED: context is connected and ready
*
* The state of a pw_context
*/
enum pw_context_state {
PW_CONTEXT_STATE_ERROR = -1,
PW_CONTEXT_STATE_UNCONNECTED = 0,
PW_CONTEXT_STATE_CONNECTING = 1,
PW_CONTEXT_STATE_CONNECTED = 2,
};
const char * pw_context_state_as_string (enum pw_context_state state);
enum pw_context_flags {
PW_CONTEXT_FLAG_NONE = 0,
PW_CONTEXT_FLAG_NO_REGISTRY = (1 << 0),
PW_CONTEXT_FLAG_NO_PROXY = (1 << 1),
};
/**
* pw_context:
*
* PipeWire context object class.
*/
struct pw_context {
char *name;
struct pw_properties *properties;
struct pw_type type;
struct pw_loop *loop;
struct pw_proxy *core_proxy;
struct pw_proxy *registry_proxy;
struct pw_map objects;
uint32_t n_types;
struct pw_map types;
SpaList global_list;
SpaList stream_list;
SpaList proxy_list;
void *protocol_private;
enum pw_context_state state;
char *error;
PW_SIGNAL (state_changed, (struct pw_listener *listener,
struct pw_context *context));
PW_SIGNAL (subscription, (struct pw_listener *listener,
struct pw_context *context,
enum pw_subscription_event event,
uint32_t type,
uint32_t id));
PW_SIGNAL (destroy_signal, (struct pw_listener *listener,
struct pw_context *context));
};
struct pw_context * pw_context_new (struct pw_loop *loop,
const char *name,
struct pw_properties *properties);
void pw_context_destroy (struct pw_context *context);
bool pw_context_connect (struct pw_context *context,
enum pw_context_flags flags);
bool pw_context_connect_fd (struct pw_context *context,
enum pw_context_flags flags,
int fd);
bool pw_context_disconnect (struct pw_context *context);
#ifdef __cplusplus
}
#endif
#endif /* __PIPEWIRE_CONTEXT_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,8 +17,8 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __PINOS_INTERFACES_H__
#define __PINOS_INTERFACES_H__
#ifndef __PIPEWIRE_INTERFACES_H__
#define __PIPEWIRE_INTERFACES_H__
#ifdef __cplusplus
extern "C" {
@ -30,27 +30,17 @@ extern "C" {
#include <spa/param-alloc.h>
#include <spa/node.h>
typedef struct _PinosClientNodeBuffer PinosClientNodeBuffer;
typedef struct _PinosInterface PinosInterface;
#include <pipewire/client/introspect.h>
#include <pinos/client/introspect.h>
#define PW_CORE_METHOD_CLIENT_UPDATE 0
#define PW_CORE_METHOD_SYNC 1
#define PW_CORE_METHOD_GET_REGISTRY 2
#define PW_CORE_METHOD_CREATE_NODE 3
#define PW_CORE_METHOD_CREATE_CLIENT_NODE 4
#define PW_CORE_METHOD_UPDATE_TYPES 5
#define PW_CORE_METHOD_NUM 6
struct _PinosInterface {
uint32_t n_methods;
const void *methods;
uint32_t n_events;
const void *events;
};
#define PINOS_CORE_METHOD_CLIENT_UPDATE 0
#define PINOS_CORE_METHOD_SYNC 1
#define PINOS_CORE_METHOD_GET_REGISTRY 2
#define PINOS_CORE_METHOD_CREATE_NODE 3
#define PINOS_CORE_METHOD_CREATE_CLIENT_NODE 4
#define PINOS_CORE_METHOD_UPDATE_TYPES 5
#define PINOS_CORE_METHOD_NUM 6
typedef struct {
struct pw_core_methods {
void (*client_update) (void *object,
const SpaDict *props);
void (*sync) (void *object,
@ -70,25 +60,25 @@ typedef struct {
uint32_t first_id,
uint32_t n_types,
const char **types);
} PinosCoreMethods;
};
#define pinos_core_do_client_update(r,...) ((PinosCoreMethods*)r->iface->methods)->client_update(r,__VA_ARGS__)
#define pinos_core_do_sync(r,...) ((PinosCoreMethods*)r->iface->methods)->sync(r,__VA_ARGS__)
#define pinos_core_do_get_registry(r,...) ((PinosCoreMethods*)r->iface->methods)->get_registry(r,__VA_ARGS__)
#define pinos_core_do_create_node(r,...) ((PinosCoreMethods*)r->iface->methods)->create_node(r,__VA_ARGS__)
#define pinos_core_do_create_client_node(r,...) ((PinosCoreMethods*)r->iface->methods)->create_client_node(r,__VA_ARGS__)
#define pinos_core_do_update_types(r,...) ((PinosCoreMethods*)r->iface->methods)->update_types(r,__VA_ARGS__)
#define pw_core_do_client_update(r,...) ((struct pw_core_methods*)r->iface->methods)->client_update(r,__VA_ARGS__)
#define pw_core_do_sync(r,...) ((struct pw_core_methods*)r->iface->methods)->sync(r,__VA_ARGS__)
#define pw_core_do_get_registry(r,...) ((struct pw_core_methods*)r->iface->methods)->get_registry(r,__VA_ARGS__)
#define pw_core_do_create_node(r,...) ((struct pw_core_methods*)r->iface->methods)->create_node(r,__VA_ARGS__)
#define pw_core_do_create_client_node(r,...) ((struct pw_core_methods*)r->iface->methods)->create_client_node(r,__VA_ARGS__)
#define pw_core_do_update_types(r,...) ((struct pw_core_methods*)r->iface->methods)->update_types(r,__VA_ARGS__)
#define PINOS_CORE_EVENT_INFO 0
#define PINOS_CORE_EVENT_DONE 1
#define PINOS_CORE_EVENT_ERROR 2
#define PINOS_CORE_EVENT_REMOVE_ID 3
#define PINOS_CORE_EVENT_UPDATE_TYPES 4
#define PINOS_CORE_EVENT_NUM 5
#define PW_CORE_EVENT_INFO 0
#define PW_CORE_EVENT_DONE 1
#define PW_CORE_EVENT_ERROR 2
#define PW_CORE_EVENT_REMOVE_ID 3
#define PW_CORE_EVENT_UPDATE_TYPES 4
#define PW_CORE_EVENT_NUM 5
typedef struct {
struct pw_core_events {
void (*info) (void *object,
PinosCoreInfo *info);
struct pw_core_info *info);
void (*done) (void *object,
uint32_t seq);
void (*error) (void *object,
@ -101,79 +91,79 @@ typedef struct {
uint32_t first_id,
uint32_t n_types,
const char **types);
} PinosCoreEvents;
};
#define pinos_core_notify_info(r,...) ((PinosCoreEvents*)r->iface->events)->info(r,__VA_ARGS__)
#define pinos_core_notify_done(r,...) ((PinosCoreEvents*)r->iface->events)->done(r,__VA_ARGS__)
#define pinos_core_notify_error(r,...) ((PinosCoreEvents*)r->iface->events)->error(r,__VA_ARGS__)
#define pinos_core_notify_remove_id(r,...) ((PinosCoreEvents*)r->iface->events)->remove_id(r,__VA_ARGS__)
#define pinos_core_notify_update_types(r,...) ((PinosCoreEvents*)r->iface->events)->update_types(r,__VA_ARGS__)
#define pw_core_notify_info(r,...) ((struct pw_core_events*)r->iface->events)->info(r,__VA_ARGS__)
#define pw_core_notify_done(r,...) ((struct pw_core_events*)r->iface->events)->done(r,__VA_ARGS__)
#define pw_core_notify_error(r,...) ((struct pw_core_events*)r->iface->events)->error(r,__VA_ARGS__)
#define pw_core_notify_remove_id(r,...) ((struct pw_core_events*)r->iface->events)->remove_id(r,__VA_ARGS__)
#define pw_core_notify_update_types(r,...) ((struct pw_core_events*)r->iface->events)->update_types(r,__VA_ARGS__)
#define PINOS_REGISTRY_METHOD_BIND 0
#define PINOS_REGISTRY_METHOD_NUM 1
#define PW_REGISTRY_METHOD_BIND 0
#define PW_REGISTRY_METHOD_NUM 1
typedef struct {
struct pw_registry_methods {
void (*bind) (void *object,
uint32_t id,
uint32_t new_id);
} PinosRegistryMethods;
};
#define pinos_registry_do_bind(r,...) ((PinosRegistryMethods*)r->iface->methods)->bind(r,__VA_ARGS__)
#define pw_registry_do_bind(r,...) ((struct pw_registry_methods*)r->iface->methods)->bind(r,__VA_ARGS__)
#define PINOS_REGISTRY_EVENT_GLOBAL 0
#define PINOS_REGISTRY_EVENT_GLOBAL_REMOVE 1
#define PINOS_REGISTRY_EVENT_NUM 2
#define PW_REGISTRY_EVENT_GLOBAL 0
#define PW_REGISTRY_EVENT_GLOBAL_REMOVE 1
#define PW_REGISTRY_EVENT_NUM 2
typedef struct {
struct pw_registry_events {
void (*global) (void *object,
uint32_t id,
const char *type);
void (*global_remove) (void *object,
uint32_t id);
} PinosRegistryEvents;
};
#define pinos_registry_notify_global(r,...) ((PinosRegistryEvents*)r->iface->events)->global(r,__VA_ARGS__)
#define pinos_registry_notify_global_remove(r,...) ((PinosRegistryEvents*)r->iface->events)->global_remove(r,__VA_ARGS__)
#define pw_registry_notify_global(r,...) ((struct pw_registry_events*)r->iface->events)->global(r,__VA_ARGS__)
#define pw_registry_notify_global_remove(r,...) ((struct pw_registry_events*)r->iface->events)->global_remove(r,__VA_ARGS__)
#define PINOS_MODULE_EVENT_INFO 0
#define PINOS_MODULE_EVENT_NUM 1
#define PW_MODULE_EVENT_INFO 0
#define PW_MODULE_EVENT_NUM 1
typedef struct {
struct pw_module_events {
void (*info) (void *object,
PinosModuleInfo *info);
} PinosModuleEvents;
struct pw_module_info *info);
};
#define pinos_module_notify_info(r,...) ((PinosModuleEvents*)r->iface->events)->info(r,__VA_ARGS__)
#define pw_module_notify_info(r,...) ((struct pw_module_events*)r->iface->events)->info(r,__VA_ARGS__)
#define PINOS_NODE_EVENT_INFO 0
#define PINOS_NODE_EVENT_NUM 1
#define PW_NODE_EVENT_INFO 0
#define PW_NODE_EVENT_NUM 1
typedef struct {
struct pw_node_events {
void (*info) (void *object,
PinosNodeInfo *info);
} PinosNodeEvents;
struct pw_node_info *info);
};
#define pinos_node_notify_info(r,...) ((PinosNodeEvents*)r->iface->events)->info(r,__VA_ARGS__)
#define pw_node_notify_info(r,...) ((struct pw_node_events*)r->iface->events)->info(r,__VA_ARGS__)
struct _PinosClientNodeBuffer {
struct pw_client_node_buffer {
uint32_t mem_id;
uint32_t offset;
uint32_t size;
SpaBuffer *buffer;
};
#define PINOS_CLIENT_NODE_METHOD_UPDATE 0
#define PINOS_CLIENT_NODE_METHOD_PORT_UPDATE 1
#define PINOS_CLIENT_NODE_METHOD_EVENT 2
#define PINOS_CLIENT_NODE_METHOD_DESTROY 3
#define PINOS_CLIENT_NODE_METHOD_NUM 4
#define PW_CLIENT_NODE_METHOD_UPDATE 0
#define PW_CLIENT_NODE_METHOD_PORT_UPDATE 1
#define PW_CLIENT_NODE_METHOD_EVENT 2
#define PW_CLIENT_NODE_METHOD_DESTROY 3
#define PW_CLIENT_NODE_METHOD_NUM 4
typedef struct {
struct pw_client_node_methods {
void (*update) (void *object,
#define PINOS_MESSAGE_NODE_UPDATE_MAX_INPUTS (1 << 0)
#define PINOS_MESSAGE_NODE_UPDATE_MAX_OUTPUTS (1 << 1)
#define PINOS_MESSAGE_NODE_UPDATE_PROPS (1 << 2)
#define PW_MESSAGE_NODE_UPDATE_MAX_INPUTS (1 << 0)
#define PW_MESSAGE_NODE_UPDATE_MAX_OUTPUTS (1 << 1)
#define PW_MESSAGE_NODE_UPDATE_PROPS (1 << 2)
uint32_t change_mask,
uint32_t max_input_ports,
uint32_t max_output_ports,
@ -182,10 +172,10 @@ typedef struct {
void (*port_update) (void *object,
SpaDirection direction,
uint32_t port_id,
#define PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0)
#define PINOS_MESSAGE_PORT_UPDATE_FORMAT (1 << 1)
#define PINOS_MESSAGE_PORT_UPDATE_PARAMS (1 << 2)
#define PINOS_MESSAGE_PORT_UPDATE_INFO (1 << 3)
#define PW_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0)
#define PW_MESSAGE_PORT_UPDATE_FORMAT (1 << 1)
#define PW_MESSAGE_PORT_UPDATE_PARAMS (1 << 2)
#define PW_MESSAGE_PORT_UPDATE_INFO (1 << 3)
uint32_t change_mask,
uint32_t n_possible_formats,
const SpaFormat **possible_formats,
@ -196,27 +186,27 @@ typedef struct {
void (*event) (void *object,
SpaEvent *event);
void (*destroy) (void *object);
} PinosClientNodeMethods;
};
#define pinos_client_node_do_update(r,...) ((PinosClientNodeMethods*)r->iface->methods)->update(r,__VA_ARGS__)
#define pinos_client_node_do_port_update(r,...) ((PinosClientNodeMethods*)r->iface->methods)->port_update(r,__VA_ARGS__)
#define pinos_client_node_do_event(r,...) ((PinosClientNodeMethods*)r->iface->methods)->event(r,__VA_ARGS__)
#define pinos_client_node_do_destroy(r) ((PinosClientNodeMethods*)r->iface->methods)->destroy(r)
#define pw_client_node_do_update(r,...) ((struct pw_client_node_methods*)r->iface->methods)->update(r,__VA_ARGS__)
#define pw_client_node_do_port_update(r,...) ((struct pw_client_node_methods*)r->iface->methods)->port_update(r,__VA_ARGS__)
#define pw_client_node_do_event(r,...) ((struct pw_client_node_methods*)r->iface->methods)->event(r,__VA_ARGS__)
#define pw_client_node_do_destroy(r) ((struct pw_client_node_methods*)r->iface->methods)->destroy(r)
#define PINOS_CLIENT_NODE_EVENT_DONE 0
#define PINOS_CLIENT_NODE_EVENT_EVENT 1
#define PINOS_CLIENT_NODE_EVENT_ADD_PORT 2
#define PINOS_CLIENT_NODE_EVENT_REMOVE_PORT 3
#define PINOS_CLIENT_NODE_EVENT_SET_FORMAT 4
#define PINOS_CLIENT_NODE_EVENT_SET_PROPERTY 5
#define PINOS_CLIENT_NODE_EVENT_ADD_MEM 6
#define PINOS_CLIENT_NODE_EVENT_USE_BUFFERS 7
#define PINOS_CLIENT_NODE_EVENT_NODE_COMMAND 8
#define PINOS_CLIENT_NODE_EVENT_PORT_COMMAND 9
#define PINOS_CLIENT_NODE_EVENT_TRANSPORT 10
#define PINOS_CLIENT_NODE_EVENT_NUM 11
#define PW_CLIENT_NODE_EVENT_DONE 0
#define PW_CLIENT_NODE_EVENT_EVENT 1
#define PW_CLIENT_NODE_EVENT_ADD_PORT 2
#define PW_CLIENT_NODE_EVENT_REMOVE_PORT 3
#define PW_CLIENT_NODE_EVENT_SET_FORMAT 4
#define PW_CLIENT_NODE_EVENT_SET_PROPERTY 5
#define PW_CLIENT_NODE_EVENT_ADD_MEM 6
#define PW_CLIENT_NODE_EVENT_USE_BUFFERS 7
#define PW_CLIENT_NODE_EVENT_NODE_COMMAND 8
#define PW_CLIENT_NODE_EVENT_PORT_COMMAND 9
#define PW_CLIENT_NODE_EVENT_TRANSPORT 10
#define PW_CLIENT_NODE_EVENT_NUM 11
typedef struct {
struct pw_client_node_events {
void (*done) (void *object,
int readfd,
int writefd);
@ -255,7 +245,7 @@ typedef struct {
SpaDirection direction,
uint32_t port_id,
uint32_t n_buffers,
PinosClientNodeBuffer *buffers);
struct pw_client_node_buffer *buffers);
void (*node_command) (void *object,
uint32_t seq,
const SpaCommand *command);
@ -266,42 +256,42 @@ typedef struct {
int memfd,
uint32_t offset,
uint32_t size);
} PinosClientNodeEvents;
};
#define pinos_client_node_notify_done(r,...) ((PinosClientNodeEvents*)r->iface->events)->done(r,__VA_ARGS__)
#define pinos_client_node_notify_event(r,...) ((PinosClientNodeEvents*)r->iface->events)->event(r,__VA_ARGS__)
#define pinos_client_node_notify_add_port(r,...) ((PinosClientNodeEvents*)r->iface->events)->add_port(r,__VA_ARGS__)
#define pinos_client_node_notify_remove_port(r,...) ((PinosClientNodeEvents*)r->iface->events)->remove_port(r,__VA_ARGS__)
#define pinos_client_node_notify_set_format(r,...) ((PinosClientNodeEvents*)r->iface->events)->set_format(r,__VA_ARGS__)
#define pinos_client_node_notify_set_property(r,...) ((PinosClientNodeEvents*)r->iface->events)->set_property(r,__VA_ARGS__)
#define pinos_client_node_notify_add_mem(r,...) ((PinosClientNodeEvents*)r->iface->events)->add_mem(r,__VA_ARGS__)
#define pinos_client_node_notify_use_buffers(r,...) ((PinosClientNodeEvents*)r->iface->events)->use_buffers(r,__VA_ARGS__)
#define pinos_client_node_notify_node_command(r,...) ((PinosClientNodeEvents*)r->iface->events)->node_command(r,__VA_ARGS__)
#define pinos_client_node_notify_port_command(r,...) ((PinosClientNodeEvents*)r->iface->events)->port_command(r,__VA_ARGS__)
#define pinos_client_node_notify_transport(r,...) ((PinosClientNodeEvents*)r->iface->events)->transport(r,__VA_ARGS__)
#define pw_client_node_notify_done(r,...) ((struct pw_client_node_events*)r->iface->events)->done(r,__VA_ARGS__)
#define pw_client_node_notify_event(r,...) ((struct pw_client_node_events*)r->iface->events)->event(r,__VA_ARGS__)
#define pw_client_node_notify_add_port(r,...) ((struct pw_client_node_events*)r->iface->events)->add_port(r,__VA_ARGS__)
#define pw_client_node_notify_remove_port(r,...) ((struct pw_client_node_events*)r->iface->events)->remove_port(r,__VA_ARGS__)
#define pw_client_node_notify_set_format(r,...) ((struct pw_client_node_events*)r->iface->events)->set_format(r,__VA_ARGS__)
#define pw_client_node_notify_set_property(r,...) ((struct pw_client_node_events*)r->iface->events)->set_property(r,__VA_ARGS__)
#define pw_client_node_notify_add_mem(r,...) ((struct pw_client_node_events*)r->iface->events)->add_mem(r,__VA_ARGS__)
#define pw_client_node_notify_use_buffers(r,...) ((struct pw_client_node_events*)r->iface->events)->use_buffers(r,__VA_ARGS__)
#define pw_client_node_notify_node_command(r,...) ((struct pw_client_node_events*)r->iface->events)->node_command(r,__VA_ARGS__)
#define pw_client_node_notify_port_command(r,...) ((struct pw_client_node_events*)r->iface->events)->port_command(r,__VA_ARGS__)
#define pw_client_node_notify_transport(r,...) ((struct pw_client_node_events*)r->iface->events)->transport(r,__VA_ARGS__)
#define PINOS_CLIENT_EVENT_INFO 0
#define PINOS_CLIENT_EVENT_NUM 1
#define PW_CLIENT_EVENT_INFO 0
#define PW_CLIENT_EVENT_NUM 1
typedef struct {
struct pw_client_events {
void (*info) (void *object,
PinosClientInfo *info);
} PinosClientEvents;
struct pw_client_info *info);
};
#define pinos_client_notify_info(r,...) ((PinosClientEvents*)r->iface->events)->info(r,__VA_ARGS__)
#define pw_client_notify_info(r,...) ((struct pw_client_events*)r->iface->events)->info(r,__VA_ARGS__)
#define PINOS_LINK_EVENT_INFO 0
#define PINOS_LINK_EVENT_NUM 1
#define PW_LINK_EVENT_INFO 0
#define PW_LINK_EVENT_NUM 1
typedef struct {
struct pw_link_events {
void (*info) (void *object,
PinosLinkInfo *info);
} PinosLinkEvents;
struct pw_link_info *info);
};
#define pinos_link_notify_info(r,...) ((PinosLinkEvents*)r->iface->events)->info(r,__VA_ARGS__)
#define pw_link_notify_info(r,...) ((struct pw_link_events*)r->iface->events)->info(r,__VA_ARGS__)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __PINOS_INTERFACES_H__ */
#endif /* __PIPEWIRE_INTERFACES_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -19,52 +19,52 @@
#include <string.h>
#include "pinos/client/pinos.h"
#include "pipewire/client/pipewire.h"
#include "pinos/client/context.h"
#include "pinos/client/subscribe.h"
#include "pipewire/client/context.h"
#include "pipewire/client/subscribe.h"
/**
* pinos_node_state_as_string:
* @state: a #PinosNodeeState
* pw_node_state_as_string:
* @state: a #enum pw_node_state
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *
pinos_node_state_as_string (PinosNodeState state)
pw_node_state_as_string (enum pw_node_state state)
{
switch (state) {
case PINOS_NODE_STATE_ERROR:
case PW_NODE_STATE_ERROR:
return "error";
case PINOS_NODE_STATE_CREATING:
case PW_NODE_STATE_CREATING:
return "creating";
case PINOS_NODE_STATE_SUSPENDED:
case PW_NODE_STATE_SUSPENDED:
return "suspended";
case PINOS_NODE_STATE_IDLE:
case PW_NODE_STATE_IDLE:
return "idle";
case PINOS_NODE_STATE_RUNNING:
case PW_NODE_STATE_RUNNING:
return "running";
}
return "invalid-state";
}
/**
* pinos_direction_as_string:
* @direction: a #PinosDirection
* pw_direction_as_string:
* @direction: a #enum pw_direction
*
* Return the string representation of @direction.
*
* Returns: the string representation of @direction.
*/
const char *
pinos_direction_as_string (PinosDirection direction)
pw_direction_as_string (enum pw_direction direction)
{
switch (direction) {
case PINOS_DIRECTION_INPUT:
case PW_DIRECTION_INPUT:
return "input";
case PINOS_DIRECTION_OUTPUT:
case PW_DIRECTION_OUTPUT:
return "output";
default:
return "invalid";
@ -73,37 +73,37 @@ pinos_direction_as_string (PinosDirection direction)
}
/**
* pinos_link_state_as_string:
* @state: a #PinosLinkeState
* pw_link_state_as_string:
* @state: a #enum pw_link_state
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const char *
pinos_link_state_as_string (PinosLinkState state)
pw_link_state_as_string (enum pw_link_state state)
{
switch (state) {
case PINOS_LINK_STATE_ERROR:
case PW_LINK_STATE_ERROR:
return "error";
case PINOS_LINK_STATE_UNLINKED:
case PW_LINK_STATE_UNLINKED:
return "unlinked";
case PINOS_LINK_STATE_INIT:
case PW_LINK_STATE_INIT:
return "init";
case PINOS_LINK_STATE_NEGOTIATING:
case PW_LINK_STATE_NEGOTIATING:
return "negotiating";
case PINOS_LINK_STATE_ALLOCATING:
case PW_LINK_STATE_ALLOCATING:
return "allocating";
case PINOS_LINK_STATE_PAUSED:
case PW_LINK_STATE_PAUSED:
return "paused";
case PINOS_LINK_STATE_RUNNING:
case PW_LINK_STATE_RUNNING:
return "running";
}
return "invalid-state";
}
static void
pinos_spa_dict_destroy (SpaDict *dict)
pw_spa_dict_destroy (SpaDict *dict)
{
SpaDictItem *item;
@ -116,7 +116,7 @@ pinos_spa_dict_destroy (SpaDict *dict)
}
static SpaDict *
pinos_spa_dict_copy (SpaDict *dict)
pw_spa_dict_copy (SpaDict *dict)
{
SpaDict *copy;
uint32_t i;
@ -144,9 +144,9 @@ no_mem:
return NULL;
}
PinosCoreInfo *
pinos_core_info_update (PinosCoreInfo *info,
const PinosCoreInfo *update)
struct pw_core_info *
pw_core_info_update (struct pw_core_info *info,
const struct pw_core_info *update)
{
uint64_t change_mask;
@ -154,7 +154,7 @@ pinos_core_info_update (PinosCoreInfo *info,
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosCoreInfo));
info = calloc (1, sizeof (struct pw_core_info));
if (info == NULL)
return NULL;
change_mask = ~0;
@ -188,14 +188,14 @@ pinos_core_info_update (PinosCoreInfo *info,
info->cookie = update->cookie;
if (update->change_mask & (1 << 5)) {
if (info->props)
pinos_spa_dict_destroy (info->props);
info->props = pinos_spa_dict_copy (update->props);
pw_spa_dict_destroy (info->props);
info->props = pw_spa_dict_copy (update->props);
}
return info;
}
void
pinos_core_info_free (PinosCoreInfo *info)
pw_core_info_free (struct pw_core_info *info)
{
if (info == NULL)
return;
@ -209,13 +209,13 @@ pinos_core_info_free (PinosCoreInfo *info)
if (info->name)
free ((void*)info->name);
if (info->props)
pinos_spa_dict_destroy (info->props);
pw_spa_dict_destroy (info->props);
free (info);
}
PinosNodeInfo *
pinos_node_info_update (PinosNodeInfo *info,
const PinosNodeInfo *update)
struct pw_node_info *
pw_node_info_update (struct pw_node_info *info,
const struct pw_node_info *update)
{
uint64_t change_mask;
int i;
@ -224,7 +224,7 @@ pinos_node_info_update (PinosNodeInfo *info,
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosNodeInfo));
info = calloc (1, sizeof (struct pw_node_info));
if (info == NULL)
return NULL;
change_mask = ~0;
@ -280,14 +280,14 @@ pinos_node_info_update (PinosNodeInfo *info,
}
if (update->change_mask & (1 << 6)) {
if (info->props)
pinos_spa_dict_destroy (info->props);
info->props = pinos_spa_dict_copy (update->props);
pw_spa_dict_destroy (info->props);
info->props = pw_spa_dict_copy (update->props);
}
return info;
}
void
pinos_node_info_free (PinosNodeInfo *info)
pw_node_info_free (struct pw_node_info *info)
{
int i;
@ -308,13 +308,13 @@ pinos_node_info_free (PinosNodeInfo *info)
if (info->error)
free ((void*)info->error);
if (info->props)
pinos_spa_dict_destroy (info->props);
pw_spa_dict_destroy (info->props);
free (info);
}
PinosModuleInfo *
pinos_module_info_update (PinosModuleInfo *info,
const PinosModuleInfo *update)
struct pw_module_info *
pw_module_info_update (struct pw_module_info *info,
const struct pw_module_info *update)
{
uint64_t change_mask;
@ -322,7 +322,7 @@ pinos_module_info_update (PinosModuleInfo *info,
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosModuleInfo));
info = calloc (1, sizeof (struct pw_module_info));
if (info == NULL)
return NULL;
change_mask = ~0;
@ -349,14 +349,14 @@ pinos_module_info_update (PinosModuleInfo *info,
}
if (update->change_mask & (1 << 3)) {
if (info->props)
pinos_spa_dict_destroy (info->props);
info->props = pinos_spa_dict_copy (update->props);
pw_spa_dict_destroy (info->props);
info->props = pw_spa_dict_copy (update->props);
}
return info;
}
void
pinos_module_info_free (PinosModuleInfo *info)
pw_module_info_free (struct pw_module_info *info)
{
if (info == NULL)
return;
@ -368,14 +368,14 @@ pinos_module_info_free (PinosModuleInfo *info)
if (info->args)
free ((void*)info->args);
if (info->props)
pinos_spa_dict_destroy (info->props);
pw_spa_dict_destroy (info->props);
free (info);
}
PinosClientInfo *
pinos_client_info_update (PinosClientInfo *info,
const PinosClientInfo *update)
struct pw_client_info *
pw_client_info_update (struct pw_client_info *info,
const struct pw_client_info *update)
{
uint64_t change_mask;
@ -383,7 +383,7 @@ pinos_client_info_update (PinosClientInfo *info,
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosClientInfo));
info = calloc (1, sizeof (struct pw_client_info));
if (info == NULL)
return NULL;
change_mask = ~0;
@ -395,25 +395,25 @@ pinos_client_info_update (PinosClientInfo *info,
if (update->change_mask & (1 << 0)) {
if (info->props)
pinos_spa_dict_destroy (info->props);
info->props = pinos_spa_dict_copy (update->props);
pw_spa_dict_destroy (info->props);
info->props = pw_spa_dict_copy (update->props);
}
return info;
}
void
pinos_client_info_free (PinosClientInfo *info)
pw_client_info_free (struct pw_client_info *info)
{
if (info == NULL)
return;
if (info->props)
pinos_spa_dict_destroy (info->props);
pw_spa_dict_destroy (info->props);
free (info);
}
PinosLinkInfo *
pinos_link_info_update (PinosLinkInfo *info,
const PinosLinkInfo *update)
struct pw_link_info *
pw_link_info_update (struct pw_link_info *info,
const struct pw_link_info *update)
{
uint64_t change_mask;
@ -421,7 +421,7 @@ pinos_link_info_update (PinosLinkInfo *info,
return info;
if (info == NULL) {
info = calloc (1, sizeof (PinosLinkInfo));
info = calloc (1, sizeof (struct pw_link_info));
if (info == NULL)
return NULL;
change_mask = ~0;
@ -444,7 +444,7 @@ pinos_link_info_update (PinosLinkInfo *info,
}
void
pinos_link_info_free (PinosLinkInfo *info)
pw_link_info_free (struct pw_link_info *info)
{
free (info);
}

View file

@ -0,0 +1,340 @@
/* PipeWire
* Copyright (C) 2015 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.
*/
#ifndef __PIPEWIRE_INTROSPECT_H__
#define __PIPEWIRE_INTROSPECT_H__
#include <spa/defs.h>
#include <spa/format.h>
#ifdef __cplusplus
extern "C" {
#endif
struct pw_context;
#include <pipewire/client/context.h>
#include <pipewire/client/properties.h>
/**
* pw_node_state:
* @PW_NODE_STATE_ERROR: the node is in error
* @PW_NODE_STATE_CREATING: the node is being created
* @PW_NODE_STATE_SUSPENDED: the node is suspended, the device might
* be closed
* @PW_NODE_STATE_IDLE: the node is running but there is no active
* port
* @PW_NODE_STATE_RUNNING: the node is running
*
* The different node states
*/
enum pw_node_state {
PW_NODE_STATE_ERROR = -1,
PW_NODE_STATE_CREATING = 0,
PW_NODE_STATE_SUSPENDED = 1,
PW_NODE_STATE_IDLE = 2,
PW_NODE_STATE_RUNNING = 3,
};
const char * pw_node_state_as_string (enum pw_node_state state);
/**
* pw_direction:
* @PW_DIRECTION_INVALID: invalid direction
* @PW_DIRECTION_INPUT: an input port
* @PW_DIRECTION_OUTPUT: an output port
*
* The direction of a port
*/
enum pw_direction {
PW_DIRECTION_INPUT = SPA_DIRECTION_INPUT,
PW_DIRECTION_OUTPUT = SPA_DIRECTION_OUTPUT
};
const char * pw_direction_as_string (enum pw_direction direction);
/**
* pw_link_state:
* @PW_LINK_STATE_ERROR: the link is in error
* @PW_LINK_STATE_UNLINKED: the link is unlinked
* @PW_LINK_STATE_INIT: the link is initialized
* @PW_LINK_STATE_NEGOTIATING: the link is negotiating formats
* @PW_LINK_STATE_ALLOCATING: the link is allocating buffers
* @PW_LINK_STATE_PAUSED: the link is paused
* @PW_LINK_STATE_RUNNING: the link is running
*
* The different link states
*/
enum pw_link_state {
PW_LINK_STATE_ERROR = -2,
PW_LINK_STATE_UNLINKED = -1,
PW_LINK_STATE_INIT = 0,
PW_LINK_STATE_NEGOTIATING = 1,
PW_LINK_STATE_ALLOCATING = 2,
PW_LINK_STATE_PAUSED = 3,
PW_LINK_STATE_RUNNING = 4,
};
const char * pw_link_state_as_string (enum pw_link_state state);
/**
* pw_core_info:
* @id: generic id of the core
* @change_mask: bitfield of changed fields since last call
* @user_name: name of the user that started the core
* @host_name: name of the machine the core is running on
* @version: version of the core
* @name: name of the core
* @cookie: a random cookie for identifying this instance of PipeWire
* @props: extra properties
*
* The core information. Extra information can be added in later
* versions.
*/
struct pw_core_info {
uint32_t id;
uint64_t change_mask;
#define PW_CORE_CHANGE_MASK_USER_NAME (1 << 0)
#define PW_CORE_CHANGE_MASK_HOST_NAME (1 << 1)
#define PW_CORE_CHANGE_MASK_VERSION (1 << 2)
#define PW_CORE_CHANGE_MASK_NAME (1 << 3)
#define PW_CORE_CHANGE_MASK_COOKIE (1 << 4)
#define PW_CORE_CHANGE_MASK_PROPS (1 << 5)
#define PW_CORE_CHANGE_MASK_ALL (~0)
const char *user_name;
const char *host_name;
const char *version;
const char *name;
uint32_t cookie;
SpaDict *props;
};
struct pw_core_info * pw_core_info_update (struct pw_core_info *info,
const struct pw_core_info *update);
void pw_core_info_free (struct pw_core_info *info);
/**
* pw_core_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_core_info
* @user_data: user data
*
* Callback with information about the PipeWire core in @info.
*/
typedef void (*pw_core_info_cb_t) (struct pw_context *c,
SpaResult res,
const struct pw_core_info *info,
void *user_data);
void pw_context_get_core_info (struct pw_context *context,
pw_core_info_cb_t cb,
void *user_data);
/**
* pw_module_info:
* @id: generic id of the module
* @change_mask: bitfield of changed fields since last call
* @props: extra properties
*
* The module information. Extra information can be added in later
* versions.
*/
struct pw_module_info {
uint32_t id;
uint64_t change_mask;
const char *name;
const char *filename;
const char *args;
SpaDict *props;
};
struct pw_module_info * pw_module_info_update (struct pw_module_info *info,
const struct pw_module_info *update);
void pw_module_info_free (struct pw_module_info *info);
/**
* pw_module_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_module_info
* @user_data: user data
*
* Callback with information about the PipeWire module in @info.
*/
typedef void (*pw_module_info_cb_t) (struct pw_context *c,
SpaResult res,
const struct pw_module_info *info,
void *user_data);
void pw_context_list_module_info (struct pw_context *context,
pw_module_info_cb_t cb,
void *user_data);
void pw_context_get_module_info_by_id (struct pw_context *context,
uint32_t id,
pw_module_info_cb_t cb,
void *user_data);
/**
* pw_client_info:
* @id: generic id of the client
* @change_mask: bitfield of changed fields since last call
* @props: extra properties
*
* The client information. Extra information can be added in later
* versions.
*/
struct pw_client_info {
uint32_t id;
uint64_t change_mask;
SpaDict *props;
};
struct pw_client_info * pw_client_info_update (struct pw_client_info *info,
const struct pw_client_info *update);
void pw_client_info_free (struct pw_client_info *info);
/**
* pw_client_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_client_info
* @user_data: user data
*
* Callback with information about the PipeWire client in @info.
*/
typedef void (*pw_client_info_cb_t) (struct pw_context *c,
SpaResult res,
const struct pw_client_info *info,
void *user_data);
void pw_context_list_client_info (struct pw_context *context,
pw_client_info_cb_t cb,
void *user_data);
void pw_context_get_client_info_by_id (struct pw_context *context,
uint32_t id,
pw_client_info_cb_t cb,
void *user_data);
/**
* pw_node_info:
* @id: generic id of the node
* @change_mask: bitfield of changed fields since last call
* @name: name the node, suitable for display
* @state: the current state of the node
* @error: an error reason if @state is error
* @props: the properties of the node
*
* The node information. Extra information can be added in later
* versions.
*/
struct pw_node_info {
uint32_t id;
uint64_t change_mask;
const char *name;
uint32_t max_inputs;
uint32_t n_inputs;
uint32_t n_input_formats;
SpaFormat **input_formats;
uint32_t max_outputs;
uint32_t n_outputs;
uint32_t n_output_formats;
SpaFormat **output_formats;
enum pw_node_state state;
const char *error;
SpaDict *props;
};
struct pw_node_info * pw_node_info_update (struct pw_node_info *info,
const struct pw_node_info *update);
void pw_node_info_free (struct pw_node_info *info);
/**
* pw_node_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_node_info
* @user_data: user data
*
* Callback with information about the PipeWire node in @info.
*/
typedef void (*pw_node_info_cb_t) (struct pw_context *c,
SpaResult res,
const struct pw_node_info *info,
void *user_data);
void pw_context_list_node_info (struct pw_context *context,
pw_node_info_cb_t cb,
void *user_data);
void pw_context_get_node_info_by_id (struct pw_context *context,
uint32_t id,
pw_node_info_cb_t cb,
void *user_data);
/**
* pw_link_info:
* @id: generic id of the link
* @change_mask: bitfield of changed fields since last call
* @output_node_path: the output node
* @output_port: the output port
* @input_node_path: the input node
* @input_port: the input port
*
* The link information. Extra information can be added in later
* versions.
*/
struct pw_link_info {
uint32_t id;
uint64_t change_mask;
uint32_t output_node_id;
uint32_t output_port_id;
uint32_t input_node_id;
uint32_t input_port_id;
};
struct pw_link_info * pw_link_info_update (struct pw_link_info *info,
const struct pw_link_info *update);
void pw_link_info_free (struct pw_link_info *info);
/**
* pw_link_info_cb_t:
* @c: a #struct pw_context
* @info: a #struct pw_link_info
* @user_data: user data
*
* Callback with information about the PipeWire link in @info.
*/
typedef void (*pw_link_info_cb_t) (struct pw_context *c,
SpaResult res,
const struct pw_link_info *info,
void *user_data);
void pw_context_list_link_info (struct pw_context *context,
pw_link_info_cb_t cb,
void *user_data);
void pw_context_get_link_info_by_id (struct pw_context *context,
uint32_t id,
pw_link_info_cb_t cb,
void *user_data);
#ifdef __cplusplus
}
#endif
#endif /* __PIPEWIRE_INTROSPECT_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -23,11 +23,11 @@
#include <spa/ringbuffer.h>
#include <pinos/client/log.h>
#include <pipewire/client/log.h>
#define DEFAULT_LOG_LEVEL SPA_LOG_LEVEL_ERROR
SpaLogLevel pinos_log_level = DEFAULT_LOG_LEVEL;
SpaLogLevel pw_log_level = DEFAULT_LOG_LEVEL;
#define TRACE_BUFFER (16*1024)
@ -101,15 +101,15 @@ static DebugLog log = {
};
SpaLog *
pinos_log_get (void)
pw_log_get (void)
{
return &log.log;
}
void
pinos_log_set_level (SpaLogLevel level)
pw_log_set_level (SpaLogLevel level)
{
pinos_log_level = level;
pw_log_level = level;
log.log.level = level;
}
@ -143,7 +143,7 @@ on_trace_event (SpaSource *source)
}
void
pinos_log_set_trace_event (SpaSource *source)
pw_log_set_trace_event (SpaSource *source)
{
log.source = source;
log.source->func = on_trace_event;
@ -151,13 +151,13 @@ pinos_log_set_trace_event (SpaSource *source)
}
void
pinos_log_log (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt, ...)
pw_log_log (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt, ...)
{
if (SPA_UNLIKELY (pinos_log_level_enabled (level))) {
if (SPA_UNLIKELY (pw_log_level_enabled (level))) {
va_list args;
va_start (args, fmt);
do_logv (&log.log, level, file, line, func, fmt, args);
@ -166,14 +166,14 @@ pinos_log_log (SpaLogLevel level,
}
void
pinos_log_logv (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt,
va_list args)
pw_log_logv (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt,
va_list args)
{
if (SPA_UNLIKELY (pinos_log_level_enabled (level))) {
if (SPA_UNLIKELY (pw_log_level_enabled (level))) {
do_logv (&log.log, level, file, line, func, fmt, args);
}
}

90
pipewire/client/log.h Normal file
View file

@ -0,0 +1,90 @@
/* PipeWire
* Copyright (C) 2015 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.
*/
#ifndef __PIPEWIRE_LOG_H__
#define __PIPEWIRE_LOG_H__
#include <spa/log.h>
#include <spa/loop.h>
#ifdef __cplusplus
extern "C" {
#endif
extern SpaLogLevel pw_log_level;
SpaLog * pw_log_get (void);
void pw_log_set_level (SpaLogLevel level);
void pw_log_set_trace_event (SpaSource *source);
void pw_log_log (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt, ...) SPA_PRINTF_FUNC(5, 6);
void pw_log_logv (SpaLogLevel level,
const char *file,
int line,
const char *func,
const char *fmt,
va_list args) SPA_PRINTF_FUNC(5, 0);
#define pw_log_level_enabled(lev) (pw_log_level >= (lev))
#if __STDC_VERSION__ >= 199901L
#define pw_log_logc(lev,...) \
if (SPA_UNLIKELY (pw_log_level_enabled (lev))) \
pw_log_log(lev,__VA_ARGS__)
#define pw_log_error(...) pw_log_logc(SPA_LOG_LEVEL_ERROR,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pw_log_warn(...) pw_log_logc(SPA_LOG_LEVEL_WARN,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pw_log_info(...) pw_log_logc(SPA_LOG_LEVEL_INFO,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pw_log_debug(...) pw_log_logc(SPA_LOG_LEVEL_DEBUG,__FILE__,__LINE__,__func__,__VA_ARGS__)
#define pw_log_trace(...) pw_log_logc(SPA_LOG_LEVEL_TRACE,__FILE__,__LINE__,__func__,__VA_ARGS__)
#else
#include <stdarg.h>
#define PW_LOG_FUNC(name,lev) \
static inline void pw_log_##name (const char *format, ...) \
{ \
if (SPA_UNLIKELY (pw_log_level_enabled (lev))) { \
va_list varargs; \
va_start (varargs, format); \
pw_log_logv (lev,__FILE__,__LINE__,__func__,format,varargs); \
va_end (varargs); \
} \
}
PW_LOG_FUNC(error, SPA_LOG_LEVEL_ERROR)
PW_LOG_FUNC(warn, SPA_LOG_LEVEL_WARN)
PW_LOG_FUNC(info, SPA_LOG_LEVEL_INFO)
PW_LOG_FUNC(debug, SPA_LOG_LEVEL_DEBUG)
PW_LOG_FUNC(trace, SPA_LOG_LEVEL_TRACE)
#endif
#ifdef __cplusplus
}
#endif
#endif /* __PIPEWIRE_LOG_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -32,22 +32,22 @@
#include <spa/loop.h>
#include <spa/ringbuffer.h>
#include <pinos/client/loop.h>
#include <pinos/client/log.h>
#include <pipewire/client/loop.h>
#include <pipewire/client/log.h>
#define DATAS_SIZE (4096 * 8)
typedef struct {
struct invoke_item {
size_t item_size;
SpaInvokeFunc func;
uint32_t seq;
size_t size;
void *data;
void *user_data;
} InvokeItem;
};
typedef struct {
PinosLoop this;
struct loop {
struct pw_loop this;
SpaList source_list;
@ -66,12 +66,12 @@ typedef struct {
SpaRingbuffer buffer;
uint8_t buffer_data[DATAS_SIZE];
} PinosLoopImpl;
};
typedef struct {
SpaSource source;
PinosLoopImpl *impl;
struct loop *impl;
SpaList link;
bool close;
@ -124,7 +124,7 @@ static SpaResult
loop_add_source (SpaLoop *loop,
SpaSource *source)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosLoopImpl, loop);
struct loop *impl = SPA_CONTAINER_OF (loop, struct loop, loop);
source->loop = loop;
@ -145,7 +145,7 @@ static SpaResult
loop_update_source (SpaSource *source)
{
SpaLoop *loop = source->loop;
PinosLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosLoopImpl, loop);
struct loop *impl = SPA_CONTAINER_OF (loop, struct loop, loop);
if (source->fd != -1) {
struct epoll_event ep;
@ -164,7 +164,7 @@ static void
loop_remove_source (SpaSource *source)
{
SpaLoop *loop = source->loop;
PinosLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosLoopImpl, loop);
struct loop *impl = SPA_CONTAINER_OF (loop, struct loop, loop);
if (source->fd != -1)
epoll_ctl (impl->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
@ -180,9 +180,9 @@ loop_invoke (SpaLoop *loop,
void *data,
void *user_data)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosLoopImpl, loop);
struct loop *impl = SPA_CONTAINER_OF (loop, struct loop, loop);
bool in_thread = pthread_equal (impl->thread, pthread_self());
InvokeItem *item;
struct invoke_item *item;
SpaResult res;
if (in_thread) {
@ -193,12 +193,12 @@ loop_invoke (SpaLoop *loop,
filled = spa_ringbuffer_get_write_index (&impl->buffer, &idx);
if (filled < 0 || filled > impl->buffer.size) {
pinos_log_warn ("data-loop %p: queue xrun %d", impl, filled);
pw_log_warn ("data-loop %p: queue xrun %d", impl, filled);
return SPA_RESULT_ERROR;
}
avail = impl->buffer.size - filled;
if (avail < sizeof (InvokeItem)) {
pinos_log_warn ("data-loop %p: queue full %d", impl, avail);
if (avail < sizeof (struct invoke_item)) {
pw_log_warn ("data-loop %p: queue full %d", impl, avail);
return SPA_RESULT_ERROR;
}
offset = idx & impl->buffer.mask;
@ -207,16 +207,16 @@ loop_invoke (SpaLoop *loop,
if (l0 > impl->buffer.size)
l0 = impl->buffer.size - l0;
item = SPA_MEMBER (impl->buffer_data, offset, InvokeItem);
item = SPA_MEMBER (impl->buffer_data, offset, struct invoke_item);
item->func = func;
item->seq = seq;
item->size = size;
item->user_data = user_data;
if (l0 > sizeof (InvokeItem) + size) {
item->data = SPA_MEMBER (item, sizeof (InvokeItem), void);
item->item_size = sizeof (InvokeItem) + size;
if (l0 < sizeof (InvokeItem) + item->item_size)
if (l0 > sizeof (struct invoke_item) + size) {
item->data = SPA_MEMBER (item, sizeof (struct invoke_item), void);
item->item_size = sizeof (struct invoke_item) + size;
if (l0 < sizeof (struct invoke_item) + item->item_size)
item->item_size = l0;
} else {
item->data = impl->buffer_data;
@ -226,7 +226,7 @@ loop_invoke (SpaLoop *loop,
spa_ringbuffer_write_update (&impl->buffer, idx + item->item_size);
pinos_loop_signal_event (&impl->this, impl->event);
pw_loop_signal_event (&impl->this, impl->event);
if (seq != SPA_ID_INVALID)
res = SPA_RESULT_RETURN_ASYNC (seq);
@ -241,11 +241,11 @@ event_func (SpaLoopUtils *utils,
SpaSource *source,
void *data)
{
PinosLoopImpl *impl = data;
struct loop *impl = data;
uint32_t index;
while (spa_ringbuffer_get_read_index (&impl->buffer, &index) > 0) {
InvokeItem *item = SPA_MEMBER (impl->buffer_data, index & impl->buffer.mask, InvokeItem);
struct invoke_item *item = SPA_MEMBER (impl->buffer_data, index & impl->buffer.mask, struct invoke_item);
item->func (impl->this.loop, true, item->seq, item->size, item->data, item->user_data);
spa_ringbuffer_read_update (&impl->buffer, index + item->item_size);
}
@ -254,7 +254,7 @@ event_func (SpaLoopUtils *utils,
static int
loop_get_fd (SpaLoopControl *ctrl)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (ctrl, PinosLoopImpl, control);
struct loop *impl = SPA_CONTAINER_OF (ctrl, struct loop, control);
return impl->epoll_fd;
}
@ -265,7 +265,7 @@ loop_set_hooks (SpaLoopControl *ctrl,
SpaLoopHook post_func,
void *data)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (ctrl, PinosLoopImpl, control);
struct loop *impl = SPA_CONTAINER_OF (ctrl, struct loop, control);
impl->pre_func = pre_func;
impl->post_func = post_func;
@ -275,14 +275,14 @@ loop_set_hooks (SpaLoopControl *ctrl,
static void
loop_enter (SpaLoopControl *ctrl)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (ctrl, PinosLoopImpl, control);
struct loop *impl = SPA_CONTAINER_OF (ctrl, struct loop, control);
impl->thread = pthread_self();
}
static void
loop_leave (SpaLoopControl *ctrl)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (ctrl, PinosLoopImpl, control);
struct loop *impl = SPA_CONTAINER_OF (ctrl, struct loop, control);
impl->thread = 0;
}
@ -290,12 +290,12 @@ static SpaResult
loop_iterate (SpaLoopControl *ctrl,
int timeout)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (ctrl, PinosLoopImpl, control);
PinosLoop *loop = &impl->this;
struct loop *impl = SPA_CONTAINER_OF (ctrl, struct loop, control);
struct pw_loop *loop = &impl->this;
struct epoll_event ep[32];
int i, nfds, save_errno;
pinos_signal_emit (&loop->before_iterate, loop);
pw_signal_emit (&loop->before_iterate, loop);
if (SPA_UNLIKELY (impl->pre_func))
impl->pre_func (ctrl, impl->hook_data);
@ -342,7 +342,7 @@ loop_add_io (SpaLoopUtils *utils,
SpaSourceIOFunc func,
void *data)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (utils, PinosLoopImpl, utils);
struct loop *impl = SPA_CONTAINER_OF (utils, struct loop, utils);
SpaSourceImpl *source;
source = calloc (1, sizeof (SpaSourceImpl));
@ -387,7 +387,7 @@ loop_add_idle (SpaLoopUtils *utils,
SpaSourceIdleFunc func,
void *data)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (utils, PinosLoopImpl, utils);
struct loop *impl = SPA_CONTAINER_OF (utils, struct loop, utils);
SpaSourceImpl *source;
source = calloc (1, sizeof (SpaSourceImpl));
@ -423,10 +423,10 @@ loop_enable_idle (SpaSource *source,
if (enabled && !impl->enabled) {
count = 1;
if (write (source->fd, &count, sizeof (uint64_t)) != sizeof (uint64_t))
pinos_log_warn ("loop %p: failed to write idle fd: %s", source, strerror (errno));
pw_log_warn ("loop %p: failed to write idle fd: %s", source, strerror (errno));
} else if (!enabled && impl->enabled) {
if (read (source->fd, &count, sizeof (uint64_t)) != sizeof (uint64_t))
pinos_log_warn ("loop %p: failed to read idle fd: %s", source, strerror (errno));
pw_log_warn ("loop %p: failed to read idle fd: %s", source, strerror (errno));
}
impl->enabled = enabled;
}
@ -438,7 +438,7 @@ source_event_func (SpaSource *source)
uint64_t count;
if (read (source->fd, &count, sizeof (uint64_t)) != sizeof (uint64_t))
pinos_log_warn ("loop %p: failed to read event fd: %s", source, strerror (errno));
pw_log_warn ("loop %p: failed to read event fd: %s", source, strerror (errno));
impl->func.event (&impl->impl->utils, source, source->data);
}
@ -448,7 +448,7 @@ loop_add_event (SpaLoopUtils *utils,
SpaSourceEventFunc func,
void *data)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (utils, PinosLoopImpl, utils);
struct loop *impl = SPA_CONTAINER_OF (utils, struct loop, utils);
SpaSourceImpl *source;
source = calloc (1, sizeof (SpaSourceImpl));
@ -477,7 +477,7 @@ loop_signal_event (SpaSource *source)
uint64_t count = 1;
if (write (source->fd, &count, sizeof(uint64_t)) != sizeof(uint64_t))
pinos_log_warn ("loop %p: failed to write event fd: %s", source, strerror (errno));
pw_log_warn ("loop %p: failed to write event fd: %s", source, strerror (errno));
}
static void
@ -487,7 +487,7 @@ source_timer_func (SpaSource *source)
uint64_t expires;
if (read (source->fd, &expires, sizeof (uint64_t)) != sizeof (uint64_t))
pinos_log_warn ("loop %p: failed to read timer fd: %s", source, strerror (errno));
pw_log_warn ("loop %p: failed to read timer fd: %s", source, strerror (errno));
impl->func.timer (&impl->impl->utils, source, source->data);
}
@ -497,7 +497,7 @@ loop_add_timer (SpaLoopUtils *utils,
SpaSourceTimerFunc func,
void *data)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (utils, PinosLoopImpl, utils);
struct loop *impl = SPA_CONTAINER_OF (utils, struct loop, utils);
SpaSourceImpl *source;
source = calloc (1, sizeof (SpaSourceImpl));
@ -555,7 +555,7 @@ source_signal_func (SpaSource *source)
struct signalfd_siginfo signal_info;
if (read (source->fd, &signal_info, sizeof (signal_info)) != sizeof (signal_info))
pinos_log_warn ("loop %p: failed to read signal fd: %s", source, strerror (errno));
pw_log_warn ("loop %p: failed to read signal fd: %s", source, strerror (errno));
impl->func.signal (&impl->impl->utils, source, impl->signal_number, source->data);
}
@ -566,7 +566,7 @@ loop_add_signal (SpaLoopUtils *utils,
SpaSourceSignalFunc func,
void *data)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (utils, PinosLoopImpl, utils);
struct loop *impl = SPA_CONTAINER_OF (utils, struct loop, utils);
SpaSourceImpl *source;
sigset_t mask;
@ -608,13 +608,13 @@ loop_destroy_source (SpaSource *source)
free (impl);
}
PinosLoop *
pinos_loop_new (void)
struct pw_loop *
pw_loop_new (void)
{
PinosLoopImpl *impl;
PinosLoop *this;
struct loop *impl;
struct pw_loop *this;
impl = calloc (1, sizeof (PinosLoopImpl));
impl = calloc (1, sizeof (struct loop));
if (impl == NULL)
return NULL;
@ -626,8 +626,8 @@ pinos_loop_new (void)
spa_list_init (&impl->source_list);
pinos_signal_init (&this->before_iterate);
pinos_signal_init (&this->destroy_signal);
pw_signal_init (&this->before_iterate);
pw_signal_init (&this->destroy_signal);
impl->loop.size = sizeof (SpaLoop);
impl->loop.add_source = loop_add_source;
@ -671,12 +671,12 @@ no_epoll:
}
void
pinos_loop_destroy (PinosLoop *loop)
pw_loop_destroy (struct pw_loop *loop)
{
PinosLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosLoopImpl, this);
struct loop *impl = SPA_CONTAINER_OF (loop, struct loop, this);
SpaSourceImpl *source, *tmp;
pinos_signal_emit (&loop->destroy_signal, loop);
pw_signal_emit (&loop->destroy_signal, loop);
spa_list_for_each_safe (source, tmp, &impl->source_list, link)
loop_destroy_source (&source->source);

76
pipewire/client/loop.h Normal file
View file

@ -0,0 +1,76 @@
/* PipeWire
* Copyright (C) 2016 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.
*/
#ifndef __PIPEWIRE_LOOP_H__
#define __PIPEWIRE_LOOP_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/list.h>
#include <spa/loop.h>
#include <pipewire/client/sig.h>
/**
* pw_loop:
*
* PipeWire loop interface.
*/
struct pw_loop {
SpaLoop *loop;
SpaLoopControl *control;
SpaLoopUtils *utils;
PW_SIGNAL (before_iterate, (struct pw_listener *listener,
struct pw_loop *loop));
PW_SIGNAL (destroy_signal, (struct pw_listener *listener,
struct pw_loop *loop));
};
struct pw_loop * pw_loop_new (void);
void pw_loop_destroy (struct pw_loop *loop);
#define pw_loop_add_source(l,...) spa_loop_add_source((l)->loop,__VA_ARGS__)
#define pw_loop_update_source(l,...) spa_loop_update_source(__VA_ARGS__)
#define pw_loop_remove_source(l,...) spa_loop_remove_source(__VA_ARGS__)
#define pw_loop_invoke(l,...) spa_loop_invoke((l)->loop,__VA_ARGS__)
#define pw_loop_get_fd(l) spa_loop_control_get_fd((l)->control)
#define pw_loop_set_hooks(l,...) spa_loop_control_set_hooks((l)->control,__VA_ARGS__)
#define pw_loop_enter(l) spa_loop_control_enter((l)->control)
#define pw_loop_iterate(l,...) spa_loop_control_iterate((l)->control,__VA_ARGS__)
#define pw_loop_leave(l) spa_loop_control_leave((l)->control)
#define pw_loop_add_io(l,...) spa_loop_utils_add_io((l)->utils,__VA_ARGS__)
#define pw_loop_update_io(l,...) spa_loop_utils_update_io((l)->utils,__VA_ARGS__)
#define pw_loop_add_idle(l,...) spa_loop_utils_add_idle((l)->utils,__VA_ARGS__)
#define pw_loop_enable_idle(l,...) spa_loop_utils_enable_idle((l)->utils,__VA_ARGS__)
#define pw_loop_add_event(l,...) spa_loop_utils_add_event((l)->utils,__VA_ARGS__)
#define pw_loop_signal_event(l,...) spa_loop_utils_signal_event((l)->utils,__VA_ARGS__)
#define pw_loop_add_timer(l,...) spa_loop_utils_add_timer((l)->utils,__VA_ARGS__)
#define pw_loop_update_timer(l,...) spa_loop_utils_update_timer((l)->utils,__VA_ARGS__)
#define pw_loop_add_signal(l,...) spa_loop_utils_add_signal((l)->utils,__VA_ARGS__)
#define pw_loop_destroy_source(l,...) spa_loop_utils_destroy_source((l)->utils,__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif /* __PIPEWIRE_LOOP_H__ */

151
pipewire/client/map.h Normal file
View file

@ -0,0 +1,151 @@
/* PipeWire
* Copyright (C) 2016 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.
*/
#ifndef __PIPEWIRE_MAP_H__
#define __PIPEWIRE_MAP_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <stdio.h>
#include <spa/defs.h>
#include <pipewire/client/array.h>
#include <pipewire/client/log.h>
union pw_map_item{
uint32_t next;
void *data;
};
struct pw_map {
struct pw_array items;
uint32_t free_list;
};
#define PW_MAP_INIT(extend) { PW_ARRAY_INIT(extend), 0 }
#define pw_map_get_size(m) pw_array_get_len (&(m)->items, union pw_map_item)
#define pw_map_get_item(m,id) pw_array_get_unchecked(&(m)->items,id,union pw_map_item)
#define pw_map_item_is_free(item) ((item)->next & 0x1)
#define pw_map_id_is_free(m,id) (pw_map_item_is_free (pw_map_get_item(m,id)))
#define pw_map_check_id(m,id) ((id) < pw_map_get_size (m))
#define pw_map_has_item(m,id) (pw_map_check_id(m,id) && !pw_map_id_is_free(m, id))
#define pw_map_lookup_unchecked(m,id) pw_map_get_item(m,id)->data
#define PW_MAP_ID_TO_PTR(id) (SPA_UINT32_TO_PTR((id)<<1))
#define PW_MAP_PTR_TO_ID(p) (SPA_PTR_TO_UINT32(p)>>1)
static inline void
pw_map_init (struct pw_map *map,
size_t size,
size_t extend)
{
pw_array_init (&map->items, extend);
pw_array_ensure_size (&map->items, size * sizeof (union pw_map_item));
map->free_list = 0;
}
static inline void
pw_map_clear (struct pw_map *map)
{
pw_array_clear (&map->items);
}
static inline uint32_t
pw_map_insert_new (struct pw_map *map,
void *data)
{
union pw_map_item *start, *item;
uint32_t id;
if (map->free_list) {
start = map->items.data;
item = &start[map->free_list >> 1];
map->free_list = item->next;
} else {
item = pw_array_add (&map->items, sizeof (union pw_map_item));
if (!item)
return SPA_ID_INVALID;
start = map->items.data;
}
item->data = data;
id = (item - start);
return id;
}
static inline bool
pw_map_insert_at (struct pw_map *map,
uint32_t id,
void *data)
{
size_t size = pw_map_get_size (map);
union pw_map_item *item;
if (id > size)
return false;
else if (id == size)
item = pw_array_add (&map->items, sizeof (union pw_map_item));
else
item = pw_map_get_item (map, id);
item->data = data;
return true;
}
static inline void
pw_map_remove (struct pw_map *map,
uint32_t id)
{
pw_map_get_item (map, id)->next = map->free_list;
map->free_list = (id << 1) | 1;
}
static inline void *
pw_map_lookup (struct pw_map *map,
uint32_t id)
{
if (SPA_LIKELY (pw_map_check_id (map, id))) {
union pw_map_item *item = pw_map_get_item (map, id);
if (!pw_map_item_is_free (item))
return item->data;
}
return NULL;
}
static inline void
pw_map_for_each (struct pw_map *map,
void (*func) (void *, void *),
void *data)
{
union pw_map_item *item;
pw_array_for_each (item, &map->items) {
if (item->data && !pw_map_item_is_free (item))
func (item->data, data);
}
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __PIPEWIRE_MAP_H__ */

View file

@ -1,4 +1,4 @@
/* Simple Plugin API
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -25,12 +25,12 @@
#include <spa/type-map.h>
#include <spa/lib/mapper.h>
#include <pinos/client/map.h>
#include <pipewire/client/map.h>
typedef struct {
SpaTypeMap map;
PinosMap types;
PinosArray strings;
SpaTypeMap map;
struct pw_map types;
struct pw_array strings;
} TypeMap;
static uint32_t
@ -42,16 +42,16 @@ type_map_get_id (SpaTypeMap *map, const char *type)
off_t o;
if (type != NULL) {
for (i = 0; i < pinos_map_get_size (&this->types); i++) {
o = (off_t) pinos_map_lookup_unchecked (&this->types, i);
for (i = 0; i < pw_map_get_size (&this->types); i++) {
o = (off_t) pw_map_lookup_unchecked (&this->types, i);
if (strcmp (SPA_MEMBER (this->strings.data, o, char), type) == 0)
return i;
}
len = strlen (type);
p = pinos_array_add (&this->strings, SPA_ROUND_UP_N (len+1, 2));
p = pw_array_add (&this->strings, SPA_ROUND_UP_N (len+1, 2));
memcpy (p, type, len+1);
o = (p - this->strings.data);
i = pinos_map_insert_new (&this->types, (void *)o);
i = pw_map_insert_new (&this->types, (void *)o);
}
return i;
}
@ -64,8 +64,8 @@ type_map_get_type (const SpaTypeMap *map, uint32_t id)
if (id == SPA_ID_INVALID)
return NULL;
if (SPA_LIKELY (pinos_map_check_id (&this->types, id))) {
off_t o = (off_t) pinos_map_lookup_unchecked (&this->types, id);
if (SPA_LIKELY (pw_map_check_id (&this->types, id))) {
off_t o = (off_t) pw_map_lookup_unchecked (&this->types, id);
return SPA_MEMBER (this->strings.data, o, char);
}
return NULL;
@ -75,7 +75,7 @@ static size_t
type_map_get_size (const SpaTypeMap *map)
{
TypeMap *this = SPA_CONTAINER_OF (map, TypeMap, map);
return pinos_map_get_size (&this->types);
return pw_map_get_size (&this->types);
}
static TypeMap default_type_map = {
@ -85,12 +85,12 @@ static TypeMap default_type_map = {
type_map_get_type,
type_map_get_size,
},
PINOS_MAP_INIT(128),
PINOS_ARRAY_INIT (4096)
PW_MAP_INIT(128),
PW_ARRAY_INIT (4096)
};
SpaTypeMap *
pinos_type_map_get_default (void)
pw_type_map_get_default (void)
{
spa_type_map_set_default (&default_type_map.map);
return &default_type_map.map;

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -31,8 +31,8 @@
#include <stdlib.h>
#include <sys/syscall.h>
#include <pinos/client/log.h>
#include <pinos/client/mem.h>
#include <pipewire/client/log.h>
#include <pipewire/client/mem.h>
/*
* No glibc wrappers exist for memfd_create(2), so provide our own.
@ -76,20 +76,20 @@ static inline int memfd_create(const char *name, unsigned int flags) {
#undef USE_MEMFD
SpaResult
pinos_memblock_map (PinosMemblock *mem)
pw_memblock_map (struct pw_memblock *mem)
{
if (mem->ptr != NULL)
return SPA_RESULT_OK;
if (mem->flags & PINOS_MEMBLOCK_FLAG_MAP_READWRITE) {
if (mem->flags & PW_MEMBLOCK_FLAG_MAP_READWRITE) {
int prot = 0;
if (mem->flags & PINOS_MEMBLOCK_FLAG_MAP_READ)
if (mem->flags & PW_MEMBLOCK_FLAG_MAP_READ)
prot |= PROT_READ;
if (mem->flags & PINOS_MEMBLOCK_FLAG_MAP_WRITE)
if (mem->flags & PW_MEMBLOCK_FLAG_MAP_WRITE)
prot |= PROT_WRITE;
if (mem->flags & PINOS_MEMBLOCK_FLAG_MAP_TWICE) {
if (mem->flags & PW_MEMBLOCK_FLAG_MAP_TWICE) {
void *ptr;
mem->ptr = mmap (NULL, mem->size << 1, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
@ -119,9 +119,9 @@ pinos_memblock_map (PinosMemblock *mem)
}
SpaResult
pinos_memblock_alloc (PinosMemblockFlags flags,
size_t size,
PinosMemblock *mem)
pw_memblock_alloc (enum pw_memblock_flags flags,
size_t size,
struct pw_memblock *mem)
{
bool use_fd;
@ -132,39 +132,39 @@ pinos_memblock_alloc (PinosMemblockFlags flags,
mem->flags = flags;
mem->size = size;
use_fd = !!(flags & (PINOS_MEMBLOCK_FLAG_MAP_TWICE | PINOS_MEMBLOCK_FLAG_WITH_FD));
use_fd = !!(flags & (PW_MEMBLOCK_FLAG_MAP_TWICE | PW_MEMBLOCK_FLAG_WITH_FD));
if (use_fd) {
#ifdef USE_MEMFD
mem->fd = memfd_create ("pinos-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
mem->fd = memfd_create ("pipewire-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (mem->fd == -1) {
pinos_log_error ("Failed to create memfd: %s\n", strerror (errno));
pw_log_error ("Failed to create memfd: %s\n", strerror (errno));
return SPA_RESULT_ERRNO;
}
#else
char filename[] = "/dev/shm/spa-tmpfile.XXXXXX";
mem->fd = mkostemp (filename, O_CLOEXEC);
if (mem->fd == -1) {
pinos_log_error ("Failed to create temporary file: %s\n", strerror (errno));
pw_log_error ("Failed to create temporary file: %s\n", strerror (errno));
return SPA_RESULT_ERRNO;
}
unlink (filename);
#endif
if (ftruncate (mem->fd, size) < 0) {
pinos_log_warn ("Failed to truncate temporary file: %s", strerror (errno));
pw_log_warn ("Failed to truncate temporary file: %s", strerror (errno));
close (mem->fd);
return SPA_RESULT_ERRNO;
}
#ifdef USE_MEMFD
if (flags & PINOS_MEMBLOCK_FLAG_SEAL) {
if (flags & PW_MEMBLOCK_FLAG_SEAL) {
unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
if (fcntl (mem->fd, F_ADD_SEALS, seals) == -1) {
pinos_log_warn ("Failed to add seals: %s", strerror (errno));
pw_log_warn ("Failed to add seals: %s", strerror (errno));
}
}
#endif
if (pinos_memblock_map (mem) != SPA_RESULT_OK)
if (pw_memblock_map (mem) != SPA_RESULT_OK)
goto mmap_failed;
} else {
mem->ptr = malloc (size);
@ -172,7 +172,7 @@ pinos_memblock_alloc (PinosMemblockFlags flags,
return SPA_RESULT_NO_MEMORY;
mem->fd = -1;
}
if (!(flags & PINOS_MEMBLOCK_FLAG_WITH_FD) && mem->fd != -1) {
if (!(flags & PW_MEMBLOCK_FLAG_WITH_FD) && mem->fd != -1) {
close (mem->fd);
mem->fd = -1;
}
@ -184,12 +184,12 @@ mmap_failed:
}
void
pinos_memblock_free (PinosMemblock *mem)
pw_memblock_free (struct pw_memblock *mem)
{
if (mem == NULL)
return;
if (mem->flags & PINOS_MEMBLOCK_FLAG_WITH_FD) {
if (mem->flags & PW_MEMBLOCK_FLAG_WITH_FD) {
if (mem->ptr)
munmap (mem->ptr, mem->size);
if (mem->fd != -1)

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,8 +17,8 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __PINOS_MEM_H__
#define __PINOS_MEM_H__
#ifndef __PIPEWIRE_MEM_H__
#define __PIPEWIRE_MEM_H__
#include <spa/defs.h>
@ -26,35 +26,33 @@
extern "C" {
#endif
typedef struct _PinosMemblock PinosMemblock;
enum pw_memblock_flags {
PW_MEMBLOCK_FLAG_NONE = 0,
PW_MEMBLOCK_FLAG_WITH_FD = (1 << 0),
PW_MEMBLOCK_FLAG_SEAL = (1 << 1),
PW_MEMBLOCK_FLAG_MAP_READ = (1 << 2),
PW_MEMBLOCK_FLAG_MAP_WRITE = (1 << 3),
PW_MEMBLOCK_FLAG_MAP_TWICE = (1 << 4),
};
typedef enum {
PINOS_MEMBLOCK_FLAG_NONE = 0,
PINOS_MEMBLOCK_FLAG_WITH_FD = (1 << 0),
PINOS_MEMBLOCK_FLAG_SEAL = (1 << 1),
PINOS_MEMBLOCK_FLAG_MAP_READ = (1 << 2),
PINOS_MEMBLOCK_FLAG_MAP_WRITE = (1 << 3),
PINOS_MEMBLOCK_FLAG_MAP_TWICE = (1 << 4),
} PinosMemblockFlags;
#define PW_MEMBLOCK_FLAG_MAP_READWRITE (PW_MEMBLOCK_FLAG_MAP_READ | PW_MEMBLOCK_FLAG_MAP_WRITE)
#define PINOS_MEMBLOCK_FLAG_MAP_READWRITE (PINOS_MEMBLOCK_FLAG_MAP_READ | PINOS_MEMBLOCK_FLAG_MAP_WRITE)
struct _PinosMemblock {
PinosMemblockFlags flags;
struct pw_memblock {
enum pw_memblock_flags flags;
int fd;
off_t offset;
void *ptr;
size_t size;
};
SpaResult pinos_memblock_alloc (PinosMemblockFlags flags,
size_t size,
PinosMemblock *mem);
SpaResult pinos_memblock_map (PinosMemblock *mem);
void pinos_memblock_free (PinosMemblock *mem);
SpaResult pw_memblock_alloc (enum pw_memblock_flags flags,
size_t size,
struct pw_memblock *mem);
SpaResult pw_memblock_map (struct pw_memblock *mem);
void pw_memblock_free (struct pw_memblock *mem);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_MEM_H__ */
#endif /* __PIPEWIRE_MEM_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or

View file

@ -1,4 +1,4 @@
pinos_headers = [
pipewire_headers = [
'array.h',
'connection.h',
'context.h',
@ -8,7 +8,7 @@ pinos_headers = [
'loop.h',
'map.h',
'mem.h',
'pinos.h',
'pipewire.h',
'properties.h',
'protocol-native.h',
'proxy.h',
@ -22,7 +22,7 @@ pinos_headers = [
'utils.h',
]
pinos_sources = [
pipewire_sources = [
'connection.c',
'context.c',
'introspect.c',
@ -34,7 +34,7 @@ pinos_sources = [
'protocol-native.c',
'proxy.c',
'stream.c',
'pinos.c',
'pipewire.c',
'rtkit.c',
'thread-mainloop.c',
'transport.c',
@ -42,26 +42,26 @@ pinos_sources = [
'utils.c',
]
install_headers(pinos_headers, subdir : 'pinos/client')
install_headers(pipewire_headers, subdir : 'pipewire/client')
libpinos_c_args = [
libpipewire_c_args = [
'-DHAVE_CONFIG_H',
'-D_GNU_SOURCE',
'-D_POSIX_C_SOURCE',
]
libpinos = shared_library('pinos', pinos_sources,
libpipewire = shared_library('pipewire', pipewire_sources,
version : libversion,
soversion : soversion,
c_args : libpinos_c_args,
c_args : libpipewire_c_args,
include_directories : [configinc, spa_inc],
link_with : spalib,
install : true,
dependencies : [dbus_dep, mathlib, pthread_lib],
)
pinos_dep = declare_dependency(link_with : libpinos,
pipewire_dep = declare_dependency(link_with : libpipewire,
include_directories : [configinc, spa_inc],
dependencies : [pthread_lib],
)

157
pipewire/client/pipewire.c Normal file
View file

@ -0,0 +1,157 @@
/* PipeWire
* Copyright (C) 2015 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 <unistd.h>
#include <stdio.h>
#include <sys/prctl.h>
#include <pwd.h>
#include "pipewire/client/pipewire.h"
/**
* pw_init:
* @argc: pointer to argc
* @argv: pointer to argv
*
* initialize the PipeWire system, parse and modify any parameters given
* by @argc and @argv.
*/
void
pw_init (int *argc, char **argv[])
{
const char *str;
if ((str = getenv ("PIPEWIRE_DEBUG")))
pw_log_set_level (atoi (str));
}
const char *
pw_get_application_name (void)
{
return NULL;
}
const char *
pw_get_prgname (void)
{
static char tcomm[16+1];
spa_zero(tcomm);
if (prctl (PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
return tcomm;
return NULL;
}
const char *
pw_get_user_name (void)
{
struct passwd *pw;
if ((pw = getpwuid (getuid ())))
return pw->pw_name;
return NULL;
}
const char *
pw_get_host_name (void)
{
static char hname[256];
if (gethostname (hname, 256) < 0)
return NULL;
hname[255] = 0;
return hname;
}
/**
* pw_client_name:
*
* Make a new PipeWire client name that can be used to construct a context.
*/
char *
pw_client_name (void)
{
char *c;
const char *cc;
if ((cc = pw_get_application_name ()))
return strdup (cc);
else if ((cc = pw_get_prgname ()))
return strdup (cc);
else {
asprintf (&c, "pipewire-pid-%zd", (size_t) getpid ());
return c;
}
}
/**
* pw_fill_context_properties:
* @properties: a #struct pw_properties
*
* Fill @properties with a set of default context properties.
*/
void
pw_fill_context_properties (struct pw_properties *properties)
{
if (!pw_properties_get (properties, "application.name"))
pw_properties_set (properties, "application.name", pw_get_application_name ());
if (!pw_properties_get (properties, "application.prgname"))
pw_properties_set (properties, "application.prgname", pw_get_prgname ());
if (!pw_properties_get (properties, "application.language")) {
pw_properties_set (properties, "application.language", getenv ("LANG"));
}
if (!pw_properties_get (properties, "application.process.id")) {
pw_properties_setf (properties, "application.process.id", "%zd", (size_t) getpid ());
}
if (!pw_properties_get (properties, "application.process.user"))
pw_properties_set (properties, "application.process.user", pw_get_user_name ());
if (!pw_properties_get (properties, "application.process.host"))
pw_properties_set (properties, "application.process.host", pw_get_host_name ());
if (!pw_properties_get (properties, "application.process.session_id")) {
pw_properties_set (properties, "application.process.session_id", getenv ("XDG_SESSION_ID"));
}
}
/**
* pw_fill_stream_properties
* @properties: a #struct pw_properties
*
* Fill @properties with a set of default stream properties.
*/
void
pw_fill_stream_properties (struct pw_properties *properties)
{
}
enum pw_direction
pw_direction_reverse (enum pw_direction direction)
{
if (direction == PW_DIRECTION_INPUT)
return PW_DIRECTION_OUTPUT;
else if (direction == PW_DIRECTION_OUTPUT)
return PW_DIRECTION_INPUT;
return direction;
}

View file

@ -0,0 +1,60 @@
/* PipeWire
* Copyright (C) 2015 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.
*/
#ifndef __PIPEWIRE_H__
#define __PIPEWIRE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <pipewire/client/context.h>
#include <pipewire/client/introspect.h>
#include <pipewire/client/log.h>
#include <pipewire/client/loop.h>
#include <pipewire/client/mem.h>
#include <pipewire/client/thread-mainloop.h>
#include <pipewire/client/properties.h>
#include <pipewire/client/stream.h>
#include <pipewire/client/subscribe.h>
#include <pipewire/client/utils.h>
#include <spa/type-map.h>
void pw_init (int *argc, char **argv[]);
const char * pw_get_application_name (void);
const char * pw_get_prgname (void);
const char * pw_get_user_name (void);
const char * pw_get_host_name (void);
char * pw_client_name (void);
void pw_fill_context_properties (struct pw_properties *properties);
void pw_fill_stream_properties (struct pw_properties *properties);
enum pw_direction pw_direction_reverse (enum pw_direction direction);
SpaTypeMap * pw_type_map_get_default (void);
#ifdef __cplusplus
}
#endif
#endif /* __PIPEWIRE_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,27 +17,27 @@
* Boston, MA 02110-1301, USA.
*/
#include "pinos/client/pinos.h"
#include "pinos/client/properties.h"
#include "pipewire/client/pipewire.h"
#include "pipewire/client/properties.h"
typedef struct {
PinosProperties this;
struct properties {
struct pw_properties this;
PinosArray items;
} PinosPropertiesImpl;
struct pw_array items;
};
static void
add_func (PinosProperties *this, char *key, char *value)
add_func (struct pw_properties *this, char *key, char *value)
{
SpaDictItem *item;
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (this, PinosPropertiesImpl, this);
struct properties *impl = SPA_CONTAINER_OF (this, struct properties, this);
item = pinos_array_add (&impl->items, sizeof (SpaDictItem));
item = pw_array_add (&impl->items, sizeof (SpaDictItem));
item->key = key;
item->value = value;
this->dict.items = impl->items.data;
this->dict.n_items = pinos_array_get_len (&impl->items, SpaDictItem);
this->dict.n_items = pw_array_get_len (&impl->items, SpaDictItem);
}
static void
@ -48,13 +48,13 @@ clear_item (SpaDictItem *item)
}
static int
find_index (PinosProperties *this, const char *key)
find_index (struct pw_properties *this, const char *key)
{
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (this, PinosPropertiesImpl, this);
int i, len = pinos_array_get_len (&impl->items, SpaDictItem);
struct properties *impl = SPA_CONTAINER_OF (this, struct properties, this);
int i, len = pw_array_get_len (&impl->items, SpaDictItem);
for (i = 0; i < len; i++) {
SpaDictItem *item = pinos_array_get_unchecked (&impl->items, i, SpaDictItem);
SpaDictItem *item = pw_array_get_unchecked (&impl->items, i, SpaDictItem);
if (strcmp (item->key, key) == 0)
return i;
}
@ -62,26 +62,26 @@ find_index (PinosProperties *this, const char *key)
}
/**
* pinos_properties_new:
* pw_properties_new:
* @key: first key
* @...: value
*
* Make a new #PinosProperties with given, NULL-terminated key/value pairs.
* Make a new #struct pw_properties with given, NULL-terminated key/value pairs.
*
* Returns: a new #PinosProperties
* Returns: a new #struct pw_properties
*/
PinosProperties *
pinos_properties_new (const char *key, ...)
struct pw_properties *
pw_properties_new (const char *key, ...)
{
PinosPropertiesImpl *impl;
struct properties *impl;
va_list varargs;
const char *value;
impl = calloc (1, sizeof (PinosPropertiesImpl));
impl = calloc (1, sizeof (struct properties));
if (impl == NULL)
return NULL;
pinos_array_init (&impl->items, 16);
pw_array_init (&impl->items, 16);
va_start (varargs, key);
while (key != NULL) {
@ -95,24 +95,24 @@ pinos_properties_new (const char *key, ...)
}
/**
* pinos_properties_new_dict:
* pw_properties_new_dict:
* @dict: a dict
*
* Make a new #PinosProperties with given @dict.
* Make a new #struct pw_properties with given @dict.
*
* Returns: a new #PinosProperties
* Returns: a new #struct pw_properties
*/
PinosProperties *
pinos_properties_new_dict (const SpaDict *dict)
struct pw_properties *
pw_properties_new_dict (const SpaDict *dict)
{
uint32_t i;
PinosPropertiesImpl *impl;
struct properties *impl;
impl = calloc (1, sizeof (PinosPropertiesImpl));
impl = calloc (1, sizeof (struct properties));
if (impl == NULL)
return NULL;
pinos_array_init (&impl->items, 16);
pw_array_init (&impl->items, 16);
for (i = 0; i < dict->n_items; i++)
add_func (&impl->this, strdup (dict->items[i].key), strdup (dict->items[i].value));
@ -121,96 +121,96 @@ pinos_properties_new_dict (const SpaDict *dict)
}
/**
* pinos_properties_copy:
* @properties: a #PinosProperties
* pw_properties_copy:
* @properties: a #struct pw_properties
*
* Make a copy of @properties.
*
* Returns: a copy of @properties
*/
PinosProperties *
pinos_properties_copy (PinosProperties *properties)
struct pw_properties *
pw_properties_copy (struct pw_properties *properties)
{
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
PinosProperties *copy;
struct properties *impl = SPA_CONTAINER_OF (properties, struct properties, this);
struct pw_properties *copy;
SpaDictItem *item;
copy = pinos_properties_new (NULL, NULL);
copy = pw_properties_new (NULL, NULL);
if (copy == NULL)
return NULL;
pinos_array_for_each (item, &impl->items)
pw_array_for_each (item, &impl->items)
add_func (copy, strdup (item->key), strdup (item->value));
return copy;
}
PinosProperties *
pinos_properties_merge (PinosProperties *oldprops,
PinosProperties *newprops)
struct pw_properties *
pw_properties_merge (struct pw_properties *oldprops,
struct pw_properties *newprops)
{
PinosProperties *res = NULL;
struct pw_properties *res = NULL;
if (oldprops == NULL) {
if (newprops == NULL)
res = NULL;
else
res = pinos_properties_copy (newprops);
res = pw_properties_copy (newprops);
} else if (newprops == NULL) {
res = pinos_properties_copy (oldprops);
res = pw_properties_copy (oldprops);
} else {
const char *key;
void * state = NULL;
res = pinos_properties_copy (oldprops);
res = pw_properties_copy (oldprops);
if (res == NULL)
return NULL;
while ((key = pinos_properties_iterate (newprops, &state))) {
pinos_properties_set (res,
while ((key = pw_properties_iterate (newprops, &state))) {
pw_properties_set (res,
key,
pinos_properties_get (newprops, key));
pw_properties_get (newprops, key));
}
}
return res;
}
/**
* pinos_properties_free:
* @properties: a #PinosProperties
* pw_properties_free:
* @properties: a #struct pw_properties
*
* Free @properties
*/
void
pinos_properties_free (PinosProperties *properties)
pw_properties_free (struct pw_properties *properties)
{
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
struct properties *impl = SPA_CONTAINER_OF (properties, struct properties, this);
SpaDictItem *item;
pinos_array_for_each (item, &impl->items)
pw_array_for_each (item, &impl->items)
clear_item (item);
pinos_array_clear (&impl->items);
pw_array_clear (&impl->items);
free (impl);
}
static void
do_replace (PinosProperties *properties,
char *key,
char *value)
do_replace (struct pw_properties *properties,
char *key,
char *value)
{
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
struct properties *impl = SPA_CONTAINER_OF (properties, struct properties, this);
int index = find_index (properties, key);
if (index == -1) {
add_func (properties, key, value);
} else {
SpaDictItem *item = pinos_array_get_unchecked (&impl->items, index, SpaDictItem);
SpaDictItem *item = pw_array_get_unchecked (&impl->items, index, SpaDictItem);
clear_item (item);
if (value == NULL) {
SpaDictItem *other = pinos_array_get_unchecked (&impl->items,
pinos_array_get_len (&impl->items, SpaDictItem) - 1,
SpaDictItem *other = pw_array_get_unchecked (&impl->items,
pw_array_get_len (&impl->items, SpaDictItem) - 1,
SpaDictItem);
item->key = other->key;
item->value = other->value;
@ -223,8 +223,8 @@ do_replace (PinosProperties *properties,
}
/**
* pinos_properties_set:
* @properties: a #PinosProperties
* pw_properties_set:
* @properties: a #struct pw_properties
* @key: a key
* @value: a value
*
@ -233,16 +233,16 @@ do_replace (PinosProperties *properties,
* removed.
*/
void
pinos_properties_set (PinosProperties *properties,
const char *key,
const char *value)
pw_properties_set (struct pw_properties *properties,
const char *key,
const char *value)
{
do_replace (properties, strdup (key), value ? strdup (value) : NULL);
}
/**
* pinos_properties_setf:
* @properties: a #PinosProperties
* pw_properties_setf:
* @properties: a #struct pw_properties
* @key: a key
* @format: a value
* @...: extra arguments
@ -251,10 +251,10 @@ pinos_properties_set (PinosProperties *properties,
* Any previous value of @key will be overwritten.
*/
void
pinos_properties_setf (PinosProperties *properties,
const char *key,
const char *format,
...)
pw_properties_setf (struct pw_properties *properties,
const char *key,
const char *format,
...)
{
va_list varargs;
char *value;
@ -267,8 +267,8 @@ pinos_properties_setf (PinosProperties *properties,
}
/**
* pinos_properties_get:
* @properties: a #PinosProperties
* pw_properties_get:
* @properties: a #struct pw_properties
* @key: a key
*
* Get the property in @properties with @key.
@ -276,21 +276,21 @@ pinos_properties_setf (PinosProperties *properties,
* Returns: the property for @key or %NULL when the key was not found
*/
const char *
pinos_properties_get (PinosProperties *properties,
const char *key)
pw_properties_get (struct pw_properties *properties,
const char *key)
{
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
struct properties *impl = SPA_CONTAINER_OF (properties, struct properties, this);
int index = find_index (properties, key);
if (index == -1)
return NULL;
return pinos_array_get_unchecked (&impl->items, index, SpaDictItem)->value;
return pw_array_get_unchecked (&impl->items, index, SpaDictItem)->value;
}
/**
* pinos_properties_iterate:
* @properties: a #PinosProperties
* pw_properties_iterate:
* @properties: a #struct pw_properties
* @state: state
*
* Iterate over @properties, returning each key in turn. @state should point
@ -303,10 +303,10 @@ pinos_properties_get (PinosProperties *properties,
* Returns: The next key or %NULL when there are no more keys to iterate.
*/
const char *
pinos_properties_iterate (PinosProperties *properties,
void **state)
pw_properties_iterate (struct pw_properties *properties,
void **state)
{
PinosPropertiesImpl *impl = SPA_CONTAINER_OF (properties, PinosPropertiesImpl, this);
struct properties *impl = SPA_CONTAINER_OF (properties, struct properties, this);
uint32_t index;
if (*state == NULL)
@ -314,10 +314,10 @@ pinos_properties_iterate (PinosProperties *properties,
else
index = SPA_PTR_TO_INT (*state);
if (!pinos_array_check_index (&impl->items, index, SpaDictItem))
if (!pw_array_check_index (&impl->items, index, SpaDictItem))
return NULL;
*state = SPA_INT_TO_PTR (index + 1);
return pinos_array_get_unchecked (&impl->items, index, SpaDictItem)->key;
return pw_array_get_unchecked (&impl->items, index, SpaDictItem)->key;
}

View file

@ -0,0 +1,57 @@
/* PipeWire
* Copyright (C) 2015 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.
*/
#ifndef __PIPEWIRE_PROPERTIES_H__
#define __PIPEWIRE_PROPERTIES_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/dict.h>
struct pw_properties {
SpaDict dict;
};
struct pw_properties * pw_properties_new (const char *key, ...);
struct pw_properties * pw_properties_new_dict (const SpaDict *dict);
struct pw_properties * pw_properties_copy (struct pw_properties *properties);
struct pw_properties * pw_properties_merge (struct pw_properties *oldprops,
struct pw_properties *newprops);
void pw_properties_free (struct pw_properties *properties);
void pw_properties_set (struct pw_properties *properties,
const char *key,
const char *value);
void pw_properties_setf (struct pw_properties *properties,
const char *key,
const char *format,
...) SPA_PRINTF_FUNC (3, 4);
const char * pw_properties_get (struct pw_properties *properties,
const char *key);
const char * pw_properties_iterate (struct pw_properties *properties,
void **state);
#ifdef __cplusplus
}
#endif
#endif /* __PIPEWIRE_PROPERTIES_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2017 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -20,18 +20,18 @@
#include <errno.h>
#include "spa/pod-iter.h"
#include "pinos/client/pinos.h"
#include "pipewire/client/pipewire.h"
#include "pinos/client/protocol-native.h"
#include "pinos/client/interfaces.h"
#include "pinos/client/connection.h"
#include "pipewire/client/protocol-native.h"
#include "pipewire/client/interfaces.h"
#include "pipewire/client/connection.h"
typedef struct {
struct builder {
SpaPODBuilder b;
PinosConnection *connection;
} Builder;
struct pw_connection *connection;
};
typedef bool (*PinosDemarshalFunc) (void *object, void *data, size_t size);
typedef bool (*demarshal_func_t) (void *object, void *data, size_t size);
static uint32_t
write_pod (SpaPODBuilder *b, uint32_t ref, const void *data, uint32_t size)
@ -41,14 +41,14 @@ write_pod (SpaPODBuilder *b, uint32_t ref, const void *data, uint32_t size)
if (b->size <= b->offset) {
b->size = SPA_ROUND_UP_N (b->offset + size, 4096);
b->data = pinos_connection_begin_write (((Builder*)b)->connection, b->size);
b->data = pw_connection_begin_write (((struct builder*)b)->connection, b->size);
}
memcpy (b->data + ref, data, size);
return ref;
}
static void
core_update_map (PinosContext *context)
core_update_map (struct pw_context *context)
{
uint32_t diff, base, i;
const char **types;
@ -62,7 +62,7 @@ core_update_map (PinosContext *context)
for (i = 0; i < diff; i++, base++)
types[i] = spa_type_map_get_type (context->type.map, base);
pinos_core_do_update_types (context->core_proxy,
pw_core_do_update_types (context->core_proxy,
context->n_types,
diff,
types);
@ -73,9 +73,9 @@ static void
core_marshal_client_update (void *object,
const SpaDict *props)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
int i, n_items;
@ -98,16 +98,16 @@ core_marshal_client_update (void *object,
}
spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f, 0);
pinos_connection_end_write (connection, proxy->id, PINOS_CORE_METHOD_CLIENT_UPDATE, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CORE_METHOD_CLIENT_UPDATE, b.b.offset);
}
static void
core_marshal_sync (void *object,
uint32_t seq)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
if (connection == NULL)
@ -118,16 +118,16 @@ core_marshal_sync (void *object,
spa_pod_builder_struct (&b.b, &f,
SPA_POD_TYPE_INT, seq);
pinos_connection_end_write (connection, proxy->id, PINOS_CORE_METHOD_SYNC, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CORE_METHOD_SYNC, b.b.offset);
}
static void
core_marshal_get_registry (void *object,
uint32_t new_id)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
if (connection == NULL)
@ -138,7 +138,7 @@ core_marshal_get_registry (void *object,
spa_pod_builder_struct (&b.b, &f,
SPA_POD_TYPE_INT, new_id);
pinos_connection_end_write (connection, proxy->id, PINOS_CORE_METHOD_GET_REGISTRY, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CORE_METHOD_GET_REGISTRY, b.b.offset);
}
static void
@ -148,9 +148,9 @@ core_marshal_create_node (void *object,
const SpaDict *props,
uint32_t new_id)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
uint32_t i, n_items;
@ -177,7 +177,7 @@ core_marshal_create_node (void *object,
SPA_POD_TYPE_INT, new_id,
-SPA_POD_TYPE_STRUCT, &f, 0);
pinos_connection_end_write (connection, proxy->id, PINOS_CORE_METHOD_CREATE_NODE, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CORE_METHOD_CREATE_NODE, b.b.offset);
}
static void
@ -186,9 +186,9 @@ core_marshal_create_client_node (void *object,
const SpaDict *props,
uint32_t new_id)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
uint32_t i, n_items;
@ -214,7 +214,7 @@ core_marshal_create_client_node (void *object,
SPA_POD_TYPE_INT, new_id,
-SPA_POD_TYPE_STRUCT, &f, 0);
pinos_connection_end_write (connection, proxy->id, PINOS_CORE_METHOD_CREATE_CLIENT_NODE, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CORE_METHOD_CREATE_CLIENT_NODE, b.b.offset);
}
static void
@ -223,9 +223,9 @@ core_marshal_update_types (void *object,
uint32_t n_types,
const char **types)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
uint32_t i;
@ -244,7 +244,7 @@ core_marshal_update_types (void *object,
spa_pod_builder_add (&b.b,
-SPA_POD_TYPE_STRUCT, &f, 0);
pinos_connection_end_write (connection, proxy->id, PINOS_CORE_METHOD_UPDATE_TYPES, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CORE_METHOD_UPDATE_TYPES, b.b.offset);
}
static bool
@ -252,9 +252,9 @@ core_demarshal_info (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaDict props;
PinosCoreInfo info;
struct pw_core_info info;
SpaPODIter it;
int i;
@ -280,7 +280,7 @@ core_demarshal_info (void *object,
0))
return false;
}
((PinosCoreEvents*)proxy->implementation)->info (proxy, &info);
((struct pw_core_events*)proxy->implementation)->info (proxy, &info);
return true;
}
@ -289,7 +289,7 @@ core_demarshal_done (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t seq;
@ -299,7 +299,7 @@ core_demarshal_done (void *object,
0))
return false;
((PinosCoreEvents*)proxy->implementation)->done (proxy, seq);
((struct pw_core_events*)proxy->implementation)->done (proxy, seq);
return true;
}
@ -308,7 +308,7 @@ core_demarshal_error (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t id, res;
const char *error;
@ -321,7 +321,7 @@ core_demarshal_error (void *object,
0))
return false;
((PinosCoreEvents*)proxy->implementation)->error (proxy, id, res, error);
((struct pw_core_events*)proxy->implementation)->error (proxy, id, res, error);
return true;
}
@ -330,7 +330,7 @@ core_demarshal_remove_id (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t id;
@ -340,7 +340,7 @@ core_demarshal_remove_id (void *object,
0))
return false;
((PinosCoreEvents*)proxy->implementation)->remove_id (proxy, id);
((struct pw_core_events*)proxy->implementation)->remove_id (proxy, id);
return true;
}
@ -349,7 +349,7 @@ core_demarshal_update_types (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t first_id, n_types;
const char **types;
@ -367,7 +367,7 @@ core_demarshal_update_types (void *object,
if (!spa_pod_iter_get (&it, SPA_POD_TYPE_STRING, &types[i], 0))
return false;
}
((PinosCoreEvents*)proxy->implementation)->update_types (proxy, first_id, n_types, types);
((struct pw_core_events*)proxy->implementation)->update_types (proxy, first_id, n_types, types);
return true;
}
@ -376,10 +376,10 @@ module_demarshal_info (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
SpaDict props;
PinosModuleInfo info;
struct pw_module_info info;
int i;
if (!spa_pod_iter_struct (&it, data, size) ||
@ -402,7 +402,7 @@ module_demarshal_info (void *object,
0))
return false;
}
((PinosModuleEvents*)proxy->implementation)->info (proxy, &info);
((struct pw_module_events*)proxy->implementation)->info (proxy, &info);
return true;
}
@ -411,14 +411,14 @@ node_demarshal_info (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
SpaDict props;
PinosNodeInfo info;
struct pw_node_info info;
int i;
if (!spa_pod_iter_struct (&it, data, size) ||
!pinos_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!pw_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get (&it,
SPA_POD_TYPE_INT, &info.id,
SPA_POD_TYPE_LONG, &info.change_mask,
@ -462,7 +462,7 @@ node_demarshal_info (void *object,
0))
return false;
}
((PinosNodeEvents*)proxy->implementation)->info (proxy, &info);
((struct pw_node_events*)proxy->implementation)->info (proxy, &info);
return true;
}
@ -473,9 +473,9 @@ client_node_marshal_update (void *object,
uint32_t max_output_ports,
const SpaProps *props)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
if (connection == NULL)
@ -489,7 +489,7 @@ client_node_marshal_update (void *object,
SPA_POD_TYPE_INT, max_output_ports,
SPA_POD_TYPE_POD, props);
pinos_connection_end_write (connection, proxy->id, PINOS_CLIENT_NODE_METHOD_UPDATE, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CLIENT_NODE_METHOD_UPDATE, b.b.offset);
}
static void
@ -504,9 +504,9 @@ client_node_marshal_port_update (void *object,
const SpaParam **params,
const SpaPortInfo *info)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f[2];
int i;
@ -548,16 +548,16 @@ client_node_marshal_port_update (void *object,
}
spa_pod_builder_add (&b.b, -SPA_POD_TYPE_STRUCT, &f[0], 0);
pinos_connection_end_write (connection, proxy->id, PINOS_CLIENT_NODE_METHOD_PORT_UPDATE, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CLIENT_NODE_METHOD_PORT_UPDATE, b.b.offset);
}
static void
client_node_marshal_event (void *object,
SpaEvent *event)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
if (connection == NULL)
@ -568,15 +568,15 @@ client_node_marshal_event (void *object,
spa_pod_builder_struct (&b.b, &f,
SPA_POD_TYPE_POD, event);
pinos_connection_end_write (connection, proxy->id, PINOS_CLIENT_NODE_METHOD_EVENT, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CLIENT_NODE_METHOD_EVENT, b.b.offset);
}
static void
client_node_marshal_destroy (void *object)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
if (connection == NULL)
@ -586,7 +586,7 @@ client_node_marshal_destroy (void *object)
spa_pod_builder_struct (&b.b, &f, 0);
pinos_connection_end_write (connection, proxy->id, PINOS_CLIENT_NODE_METHOD_DESTROY, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_CLIENT_NODE_METHOD_DESTROY, b.b.offset);
}
static bool
@ -594,9 +594,9 @@ client_node_demarshal_done (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
PinosConnection *connection = proxy->context->protocol_private;
struct pw_connection *connection = proxy->context->protocol_private;
int32_t ridx, widx;
int readfd, writefd;
@ -607,12 +607,12 @@ client_node_demarshal_done (void *object,
0))
return false;
readfd = pinos_connection_get_fd (connection, ridx);
writefd = pinos_connection_get_fd (connection, widx);
readfd = pw_connection_get_fd (connection, ridx);
writefd = pw_connection_get_fd (connection, widx);
if (readfd == -1 || writefd == -1)
return false;
((PinosClientNodeEvents*)proxy->implementation)->done (proxy, readfd, writefd);
((struct pw_client_node_events*)proxy->implementation)->done (proxy, readfd, writefd);
return true;
}
@ -621,18 +621,18 @@ client_node_demarshal_event (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
const SpaEvent *event;
if (!spa_pod_iter_struct (&it, data, size) ||
!pinos_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!pw_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get (&it,
SPA_POD_TYPE_OBJECT, &event,
0))
return false;
((PinosClientNodeEvents*)proxy->implementation)->event (proxy, event);
((struct pw_client_node_events*)proxy->implementation)->event (proxy, event);
return true;
}
@ -641,7 +641,7 @@ client_node_demarshal_add_port (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
int32_t seq, direction, port_id;
@ -653,7 +653,7 @@ client_node_demarshal_add_port (void *object,
0))
return false;
((PinosClientNodeEvents*)proxy->implementation)->add_port (proxy, seq, direction, port_id);
((struct pw_client_node_events*)proxy->implementation)->add_port (proxy, seq, direction, port_id);
return true;
}
@ -662,7 +662,7 @@ client_node_demarshal_remove_port (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
int32_t seq, direction, port_id;
@ -674,7 +674,7 @@ client_node_demarshal_remove_port (void *object,
0))
return false;
((PinosClientNodeEvents*)proxy->implementation)->remove_port (proxy, seq, direction, port_id);
((struct pw_client_node_events*)proxy->implementation)->remove_port (proxy, seq, direction, port_id);
return true;
}
@ -683,13 +683,13 @@ client_node_demarshal_set_format (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t seq, direction, port_id, flags;
const SpaFormat *format = NULL;
if (!spa_pod_iter_struct (&it, data, size) ||
!pinos_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!pw_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get (&it,
SPA_POD_TYPE_INT, &seq,
SPA_POD_TYPE_INT, &direction,
@ -699,7 +699,7 @@ client_node_demarshal_set_format (void *object,
0))
return false;
((PinosClientNodeEvents*)proxy->implementation)->set_format (proxy, seq, direction, port_id,
((struct pw_client_node_events*)proxy->implementation)->set_format (proxy, seq, direction, port_id,
flags, format);
return true;
}
@ -709,7 +709,7 @@ client_node_demarshal_set_property (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t seq, id;
const void *value;
@ -723,7 +723,7 @@ client_node_demarshal_set_property (void *object,
0))
return false;
((PinosClientNodeEvents*)proxy->implementation)->set_property (proxy, seq, id, s, value);
((struct pw_client_node_events*)proxy->implementation)->set_property (proxy, seq, id, s, value);
return true;
}
@ -732,14 +732,14 @@ client_node_demarshal_add_mem (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
PinosConnection *connection = proxy->context->protocol_private;
struct pw_connection *connection = proxy->context->protocol_private;
uint32_t direction, port_id, mem_id, type, memfd_idx, flags, offset, sz;
int memfd;
if (!spa_pod_iter_struct (&it, data, size) ||
!pinos_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!pw_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get (&it,
SPA_POD_TYPE_INT, &direction,
SPA_POD_TYPE_INT, &port_id,
@ -752,9 +752,9 @@ client_node_demarshal_add_mem (void *object,
0))
return false;
memfd = pinos_connection_get_fd (connection, memfd_idx);
memfd = pw_connection_get_fd (connection, memfd_idx);
((PinosClientNodeEvents*)proxy->implementation)->add_mem (proxy,
((struct pw_client_node_events*)proxy->implementation)->add_mem (proxy,
direction,
port_id,
mem_id,
@ -771,14 +771,14 @@ client_node_demarshal_use_buffers (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t seq, direction, port_id, n_buffers, data_id;
PinosClientNodeBuffer *buffers;
struct pw_client_node_buffer *buffers;
int i, j;
if (!spa_pod_iter_struct (&it, data, size) ||
!pinos_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!pw_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get (&it,
SPA_POD_TYPE_INT, &seq,
SPA_POD_TYPE_INT, &direction,
@ -787,7 +787,7 @@ client_node_demarshal_use_buffers (void *object,
0))
return false;
buffers = alloca (sizeof (PinosClientNodeBuffer) * n_buffers);
buffers = alloca (sizeof (struct pw_client_node_buffer) * n_buffers);
for (i = 0; i < n_buffers; i++) {
SpaBuffer *buf = buffers[i].buffer = alloca (sizeof (SpaBuffer));
@ -827,7 +827,7 @@ client_node_demarshal_use_buffers (void *object,
d->data = SPA_UINT32_TO_PTR (data_id);
}
}
((PinosClientNodeEvents*)proxy->implementation)->use_buffers (proxy,
((struct pw_client_node_events*)proxy->implementation)->use_buffers (proxy,
seq,
direction,
port_id,
@ -841,20 +841,20 @@ client_node_demarshal_node_command (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
const SpaCommand *command;
uint32_t seq;
if (!spa_pod_iter_struct (&it, data, size) ||
!pinos_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!pw_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get (&it,
SPA_POD_TYPE_INT, &seq,
SPA_POD_TYPE_OBJECT, &command,
0))
return false;
((PinosClientNodeEvents*)proxy->implementation)->node_command (proxy, seq, command);
((struct pw_client_node_events*)proxy->implementation)->node_command (proxy, seq, command);
return true;
}
@ -863,20 +863,20 @@ client_node_demarshal_port_command (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
const SpaCommand *command;
uint32_t port_id;
if (!spa_pod_iter_struct (&it, data, size) ||
!pinos_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!pw_pod_remap_data (SPA_POD_TYPE_STRUCT, data, size, &proxy->context->types) ||
!spa_pod_iter_get (&it,
SPA_POD_TYPE_INT, &port_id,
SPA_POD_TYPE_OBJECT, &command,
0))
return false;
((PinosClientNodeEvents*)proxy->implementation)->port_command (proxy, port_id, command);
((struct pw_client_node_events*)proxy->implementation)->port_command (proxy, port_id, command);
return true;
}
@ -885,9 +885,9 @@ client_node_demarshal_transport (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
PinosConnection *connection = proxy->context->protocol_private;
struct pw_connection *connection = proxy->context->protocol_private;
uint32_t memfd_idx, offset, sz;
int memfd;
@ -899,8 +899,8 @@ client_node_demarshal_transport (void *object,
0))
return false;
memfd = pinos_connection_get_fd (connection, memfd_idx);
((PinosClientNodeEvents*)proxy->implementation)->transport (proxy, memfd, offset, sz);
memfd = pw_connection_get_fd (connection, memfd_idx);
((struct pw_client_node_events*)proxy->implementation)->transport (proxy, memfd, offset, sz);
return true;
}
@ -909,10 +909,10 @@ client_demarshal_info (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
SpaDict props;
PinosClientInfo info;
struct pw_client_info info;
uint32_t i;
if (!spa_pod_iter_struct (&it, data, size) ||
@ -932,7 +932,7 @@ client_demarshal_info (void *object,
0))
return false;
}
((PinosClientEvents*)proxy->implementation)->info (proxy, &info);
((struct pw_client_events*)proxy->implementation)->info (proxy, &info);
return true;
}
@ -941,9 +941,9 @@ link_demarshal_info (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
PinosLinkInfo info;
struct pw_link_info info;
if (!spa_pod_iter_struct (&it, data, size) ||
!spa_pod_iter_get (&it,
@ -956,7 +956,7 @@ link_demarshal_info (void *object,
0))
return false;
((PinosLinkEvents*)proxy->implementation)->info (proxy, &info);
((struct pw_link_events*)proxy->implementation)->info (proxy, &info);
return true;
}
@ -965,7 +965,7 @@ registry_demarshal_global (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t id;
const char *type;
@ -977,7 +977,7 @@ registry_demarshal_global (void *object,
0))
return false;
((PinosRegistryEvents*)proxy->implementation)->global (proxy, id, type);
((struct pw_registry_events*)proxy->implementation)->global (proxy, id, type);
return true;
}
@ -986,7 +986,7 @@ registry_demarshal_global_remove (void *object,
void *data,
size_t size)
{
PinosProxy *proxy = object;
struct pw_proxy *proxy = object;
SpaPODIter it;
uint32_t id;
@ -996,7 +996,7 @@ registry_demarshal_global_remove (void *object,
0))
return false;
((PinosRegistryEvents*)proxy->implementation)->global_remove (proxy, id);
((struct pw_registry_events*)proxy->implementation)->global_remove (proxy, id);
return true;
}
@ -1005,9 +1005,9 @@ registry_marshal_bind (void *object,
uint32_t id,
uint32_t new_id)
{
PinosProxy *proxy = object;
PinosConnection *connection = proxy->context->protocol_private;
Builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
struct pw_proxy *proxy = object;
struct pw_connection *connection = proxy->context->protocol_private;
struct builder b = { { NULL, 0, 0, NULL, write_pod }, connection };
SpaPODFrame f;
if (connection == NULL)
@ -1019,10 +1019,10 @@ registry_marshal_bind (void *object,
SPA_POD_TYPE_INT, id,
SPA_POD_TYPE_INT, new_id);
pinos_connection_end_write (connection, proxy->id, PINOS_REGISTRY_METHOD_BIND, b.b.offset);
pw_connection_end_write (connection, proxy->id, PW_REGISTRY_METHOD_BIND, b.b.offset);
}
static const PinosCoreMethods pinos_protocol_native_client_core_methods = {
static const struct pw_core_methods pw_protocol_native_client_core_methods = {
&core_marshal_client_update,
&core_marshal_sync,
&core_marshal_get_registry,
@ -1031,7 +1031,7 @@ static const PinosCoreMethods pinos_protocol_native_client_core_methods = {
&core_marshal_update_types,
};
static const PinosDemarshalFunc pinos_protocol_native_client_core_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_core_demarshal[] = {
&core_demarshal_info,
&core_demarshal_done,
&core_demarshal_error,
@ -1039,33 +1039,33 @@ static const PinosDemarshalFunc pinos_protocol_native_client_core_demarshal[] =
&core_demarshal_update_types,
};
static const PinosInterface pinos_protocol_native_client_core_interface = {
PINOS_CORE_METHOD_NUM, &pinos_protocol_native_client_core_methods,
PINOS_CORE_EVENT_NUM, pinos_protocol_native_client_core_demarshal
static const struct pw_interface pw_protocol_native_client_core_interface = {
PW_CORE_METHOD_NUM, &pw_protocol_native_client_core_methods,
PW_CORE_EVENT_NUM, pw_protocol_native_client_core_demarshal
};
static const PinosRegistryMethods pinos_protocol_native_client_registry_methods = {
static const struct pw_registry_methods pw_protocol_native_client_registry_methods = {
&registry_marshal_bind
};
static const PinosDemarshalFunc pinos_protocol_native_client_registry_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_registry_demarshal[] = {
&registry_demarshal_global,
&registry_demarshal_global_remove,
};
static const PinosInterface pinos_protocol_native_client_registry_interface = {
PINOS_REGISTRY_METHOD_NUM, &pinos_protocol_native_client_registry_methods,
PINOS_REGISTRY_EVENT_NUM, pinos_protocol_native_client_registry_demarshal,
static const struct pw_interface pw_protocol_native_client_registry_interface = {
PW_REGISTRY_METHOD_NUM, &pw_protocol_native_client_registry_methods,
PW_REGISTRY_EVENT_NUM, pw_protocol_native_client_registry_demarshal,
};
static const PinosClientNodeMethods pinos_protocol_native_client_client_node_methods = {
static const struct pw_client_node_methods pw_protocol_native_client_client_node_methods = {
&client_node_marshal_update,
&client_node_marshal_port_update,
&client_node_marshal_event,
&client_node_marshal_destroy
};
static const PinosDemarshalFunc pinos_protocol_native_client_client_node_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_client_node_demarshal[] = {
&client_node_demarshal_done,
&client_node_demarshal_event,
&client_node_demarshal_add_port,
@ -1079,72 +1079,72 @@ static const PinosDemarshalFunc pinos_protocol_native_client_client_node_demarsh
&client_node_demarshal_transport
};
static const PinosInterface pinos_protocol_native_client_client_node_interface = {
PINOS_CLIENT_NODE_METHOD_NUM, &pinos_protocol_native_client_client_node_methods,
PINOS_CLIENT_NODE_EVENT_NUM, pinos_protocol_native_client_client_node_demarshal,
static const struct pw_interface pw_protocol_native_client_client_node_interface = {
PW_CLIENT_NODE_METHOD_NUM, &pw_protocol_native_client_client_node_methods,
PW_CLIENT_NODE_EVENT_NUM, pw_protocol_native_client_client_node_demarshal,
};
static const PinosDemarshalFunc pinos_protocol_native_client_module_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_module_demarshal[] = {
&module_demarshal_info,
};
static const PinosInterface pinos_protocol_native_client_module_interface = {
static const struct pw_interface pw_protocol_native_client_module_interface = {
0, NULL,
PINOS_MODULE_EVENT_NUM, pinos_protocol_native_client_module_demarshal,
PW_MODULE_EVENT_NUM, pw_protocol_native_client_module_demarshal,
};
static const PinosDemarshalFunc pinos_protocol_native_client_node_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_node_demarshal[] = {
&node_demarshal_info,
};
static const PinosInterface pinos_protocol_native_client_node_interface = {
static const struct pw_interface pw_protocol_native_client_node_interface = {
0, NULL,
PINOS_NODE_EVENT_NUM, pinos_protocol_native_client_node_demarshal,
PW_NODE_EVENT_NUM, pw_protocol_native_client_node_demarshal,
};
static const PinosDemarshalFunc pinos_protocol_native_client_client_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_client_demarshal[] = {
&client_demarshal_info,
};
static const PinosInterface pinos_protocol_native_client_client_interface = {
static const struct pw_interface pw_protocol_native_client_client_interface = {
0, NULL,
PINOS_CLIENT_EVENT_NUM, pinos_protocol_native_client_client_demarshal,
PW_CLIENT_EVENT_NUM, pw_protocol_native_client_client_demarshal,
};
static const PinosDemarshalFunc pinos_protocol_native_client_link_demarshal[] = {
static const demarshal_func_t pw_protocol_native_client_link_demarshal[] = {
&link_demarshal_info,
};
static const PinosInterface pinos_protocol_native_client_link_interface = {
static const struct pw_interface pw_protocol_native_client_link_interface = {
0, NULL,
PINOS_LINK_EVENT_NUM, pinos_protocol_native_client_link_demarshal,
PW_LINK_EVENT_NUM, pw_protocol_native_client_link_demarshal,
};
bool
pinos_protocol_native_client_setup (PinosProxy *proxy)
pw_protocol_native_client_setup (struct pw_proxy *proxy)
{
const PinosInterface *iface;
const struct pw_interface *iface;
if (proxy->type == proxy->context->type.core) {
iface = &pinos_protocol_native_client_core_interface;
iface = &pw_protocol_native_client_core_interface;
}
else if (proxy->type == proxy->context->type.registry) {
iface = &pinos_protocol_native_client_registry_interface;
iface = &pw_protocol_native_client_registry_interface;
}
else if (proxy->type == proxy->context->type.module) {
iface = &pinos_protocol_native_client_module_interface;
iface = &pw_protocol_native_client_module_interface;
}
else if (proxy->type == proxy->context->type.node) {
iface = &pinos_protocol_native_client_node_interface;
iface = &pw_protocol_native_client_node_interface;
}
else if (proxy->type == proxy->context->type.client_node) {
iface = &pinos_protocol_native_client_client_node_interface;
iface = &pw_protocol_native_client_client_node_interface;
}
else if (proxy->type == proxy->context->type.client) {
iface = &pinos_protocol_native_client_client_interface;
iface = &pw_protocol_native_client_client_interface;
}
else if (proxy->type == proxy->context->type.link) {
iface = &pinos_protocol_native_client_link_interface;
iface = &pw_protocol_native_client_link_interface;
} else
return false;
proxy->iface = iface;

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2017 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
#include "pinos/client/pinos.h"
#include "pinos/client/interfaces.h"
#include "pipewire/client/pipewire.h"
#include "pipewire/client/interfaces.h"
bool pinos_protocol_native_client_setup (PinosProxy *proxy);
bool pw_protocol_native_client_setup (struct pw_proxy *proxy);

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,23 +17,23 @@
* Boston, MA 02110-1301, USA.
*/
#include <pinos/client/log.h>
#include <pinos/client/proxy.h>
#include <pinos/client/protocol-native.h>
#include <pipewire/client/log.h>
#include <pipewire/client/proxy.h>
#include <pipewire/client/protocol-native.h>
typedef struct {
PinosProxy this;
} PinosProxyImpl;
struct proxy {
struct pw_proxy this;
};
PinosProxy *
pinos_proxy_new (PinosContext *context,
uint32_t id,
uint32_t type)
struct pw_proxy *
pw_proxy_new (struct pw_context *context,
uint32_t id,
uint32_t type)
{
PinosProxyImpl *impl;
PinosProxy *this;
struct proxy *impl;
struct pw_proxy *this;
impl = calloc (1, sizeof (PinosProxyImpl));
impl = calloc (1, sizeof (struct proxy));
if (impl == NULL)
return NULL;
@ -41,38 +41,38 @@ pinos_proxy_new (PinosContext *context,
this->context = context;
this->type = type;
pinos_signal_init (&this->destroy_signal);
pw_signal_init (&this->destroy_signal);
if (id == SPA_ID_INVALID) {
id = pinos_map_insert_new (&context->objects, this);
} else if (!pinos_map_insert_at (&context->objects, id, this))
id = pw_map_insert_new (&context->objects, this);
} else if (!pw_map_insert_at (&context->objects, id, this))
goto in_use;
this->id = id;
pinos_protocol_native_client_setup (this);
pw_protocol_native_client_setup (this);
spa_list_insert (&this->context->proxy_list, &this->link);
pinos_log_trace ("proxy %p: new %u", this, this->id);
pw_log_trace ("proxy %p: new %u", this, this->id);
return this;
in_use:
pinos_log_error ("proxy %p: id %u in use for context %p", this, id, context);
pw_log_error ("proxy %p: id %u in use for context %p", this, id, context);
free (impl);
return NULL;
}
void
pinos_proxy_destroy (PinosProxy *proxy)
pw_proxy_destroy (struct pw_proxy *proxy)
{
PinosProxyImpl *impl = SPA_CONTAINER_OF (proxy, PinosProxyImpl, this);
struct proxy *impl = SPA_CONTAINER_OF (proxy, struct proxy, this);
pinos_log_trace ("proxy %p: destroy %u", proxy, proxy->id);
pinos_signal_emit (&proxy->destroy_signal, proxy);
pw_log_trace ("proxy %p: destroy %u", proxy, proxy->id);
pw_signal_emit (&proxy->destroy_signal, proxy);
pinos_map_remove (&proxy->context->objects, proxy->id);
pw_map_remove (&proxy->context->objects, proxy->id);
spa_list_remove (&proxy->link);
free (impl);

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,42 +17,40 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __PINOS_PROXY_H__
#define __PINOS_PROXY_H__
#ifndef __PIPEWIRE_PROXY_H__
#define __PIPEWIRE_PROXY_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PinosProxy PinosProxy;
#include <pipewire/client/connection.h>
#include <pipewire/client/context.h>
#include <pipewire/client/type.h>
#include <pinos/client/connection.h>
#include <pinos/client/context.h>
#include <pinos/client/interfaces.h>
struct _PinosProxy {
PinosContext *context;
SpaList link;
struct pw_proxy {
struct pw_context *context;
SpaList link;
uint32_t id;
uint32_t type;
const PinosInterface *iface;
const void *implementation;
const struct pw_interface *iface;
const void *implementation;
void *user_data;
PINOS_SIGNAL (destroy_signal, (PinosListener *listener,
PinosProxy *proxy));
PW_SIGNAL (destroy_signal, (struct pw_listener *listener,
struct pw_proxy *proxy));
};
PinosProxy * pinos_proxy_new (PinosContext *context,
uint32_t id,
uint32_t type);
void pinos_proxy_destroy (PinosProxy *proxy);
struct pw_proxy * pw_proxy_new (struct pw_context *context,
uint32_t id,
uint32_t type);
void pw_proxy_destroy (struct pw_proxy *proxy);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_PROXY_H__ */
#endif /* __PIPEWIRE_PROXY_H__ */

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -47,23 +47,23 @@
#include <dbus/dbus.h>
#include <pinos/client/log.h>
#include <pipewire/client/log.h>
#include "rtkit.h"
struct _PinosRTKitBus {
struct pw_rtkit_bus {
DBusConnection *bus;
};
PinosRTKitBus *
pinos_rtkit_bus_get_system (void)
struct pw_rtkit_bus *
pw_rtkit_bus_get_system (void)
{
PinosRTKitBus *bus;
struct pw_rtkit_bus *bus;
DBusError error;
dbus_error_init(&error);
bus = calloc (1, sizeof (PinosRTKitBus));
bus = calloc (1, sizeof (struct pw_rtkit_bus));
if (bus == NULL)
return NULL;
@ -76,13 +76,13 @@ pinos_rtkit_bus_get_system (void)
return bus;
error:
pinos_log_error ("Failed to connect to system bus: %s", error.message);
pw_log_error ("Failed to connect to system bus: %s", error.message);
dbus_error_free (&error);
return NULL;
}
void
pinos_rtkit_bus_free (PinosRTKitBus *system_bus)
pw_rtkit_bus_free (struct pw_rtkit_bus *system_bus)
{
dbus_connection_close (system_bus->bus);
dbus_connection_unref (system_bus->bus);
@ -122,7 +122,7 @@ static int translate_error(const char *name) {
return -EIO;
}
static long long rtkit_get_int_property(PinosRTKitBus *connection, const char* propname, long long* propval) {
static long long rtkit_get_int_property(struct pw_rtkit_bus *connection, const char* propname, long long* propval) {
DBusMessage *m = NULL, *r = NULL;
DBusMessageIter iter, subiter;
dbus_int64_t i64;
@ -202,7 +202,7 @@ finish:
return ret;
}
int pinos_rtkit_get_max_realtime_priority(PinosRTKitBus *connection) {
int pw_rtkit_get_max_realtime_priority(struct pw_rtkit_bus *connection) {
long long retval;
int err;
@ -210,7 +210,7 @@ int pinos_rtkit_get_max_realtime_priority(PinosRTKitBus *connection) {
return err < 0 ? err : retval;
}
int pinos_rtkit_get_min_nice_level(PinosRTKitBus *connection, int* min_nice_level) {
int pw_rtkit_get_min_nice_level(struct pw_rtkit_bus *connection, int* min_nice_level) {
long long retval;
int err;
@ -220,7 +220,7 @@ int pinos_rtkit_get_min_nice_level(PinosRTKitBus *connection, int* min_nice_leve
return err;
}
long long pinos_rtkit_get_rttime_usec_max(PinosRTKitBus *connection) {
long long pw_rtkit_get_rttime_usec_max(struct pw_rtkit_bus *connection) {
long long retval;
int err;
@ -229,7 +229,7 @@ long long pinos_rtkit_get_rttime_usec_max(PinosRTKitBus *connection) {
}
int
pinos_rtkit_make_realtime (PinosRTKitBus *connection,
pw_rtkit_make_realtime (struct pw_rtkit_bus *connection,
pid_t thread,
int priority)
{
@ -292,7 +292,7 @@ finish:
}
int
pinos_rtkit_make_high_priority (PinosRTKitBus *connection,
pw_rtkit_make_high_priority (struct pw_rtkit_bus *connection,
pid_t thread,
int nice_level)
{
@ -358,23 +358,23 @@ finish:
#else
int pinos_rtkit_make_realtime(PinosRTKitBus *connection, pid_t thread, int priority) {
int pw_rtkit_make_realtime(struct pw_rtkit_bus *connection, pid_t thread, int priority) {
return -ENOTSUP;
}
int pinos_rtkit_make_high_priority(PinosRTKitBus *connection, pid_t thread, int nice_level) {
int pw_rtkit_make_high_priority(struct pw_rtkit_bus *connection, pid_t thread, int nice_level) {
return -ENOTSUP;
}
int pinos_rtkit_get_max_realtime_priority(PinosRTKitBus *connection) {
int pw_rtkit_get_max_realtime_priority(struct pw_rtkit_bus *connection) {
return -ENOTSUP;
}
int pinos_rtkit_get_min_nice_level(PinosRTKitBus *connection, int* min_nice_level) {
int pw_rtkit_get_min_nice_level(struct pw_rtkit_bus *connection, int* min_nice_level) {
return -ENOTSUP;
}
long long pinos_rtkit_get_rttime_usec_max(PinosRTKitBus *connection) {
long long pw_rtkit_get_rttime_usec_max(struct pw_rtkit_bus *connection) {
return -ENOTSUP;
}

View file

@ -1,4 +1,4 @@
/* Pinos
/* PipeWire
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
@ -17,8 +17,8 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __PINOS_RTKIT_H__
#define __PINOS_RTKIT_H__
#ifndef __PIPEWIRE_RTKIT_H__
#define __PIPEWIRE_RTKIT_H__
#include <sys/types.h>
#include <unistd.h>
@ -30,10 +30,8 @@ extern "C" {
#define RTKIT_SERVICE_NAME "org.freedesktop.RealtimeKit1"
#define RTKIT_OBJECT_PATH "/org/freedesktop/RealtimeKit1"
typedef struct _PinosRTKitBus PinosRTKitBus;
PinosRTKitBus * pinos_rtkit_bus_get_system (void);
void pinos_rtkit_bus_free (PinosRTKitBus *system_bus);
struct pw_rtkit_bus * pw_rtkit_bus_get_system (void);
void pw_rtkit_bus_free (struct pw_rtkit_bus *system_bus);
/* This is mostly equivalent to sched_setparam(thread, SCHED_RR, {
@ -41,9 +39,9 @@ void pinos_rtkit_bus_free (PinosRTKitBus *system_bus);
* id as returned by gettid(), not a pthread_t! If 'thread' is 0 the
* current thread is used. The returned value is a negative errno
* style error code, or 0 on success. */
int pinos_rtkit_make_realtime (PinosRTKitBus *system_bus,
pid_t thread,
int priority);
int pw_rtkit_make_realtime (struct pw_rtkit_bus *system_bus,
pid_t thread,
int priority);
/* This is mostly equivalent to setpriority(PRIO_PROCESS, thread,
@ -51,28 +49,28 @@ int pinos_rtkit_make_realtime (PinosRTKitBus *system
* gettid(), not a pthread_t! If 'thread' is 0 the current thread is
* used. The returned value is a negative errno style error code, or
* 0 on success. */
int pinos_rtkit_make_high_priority (PinosRTKitBus *system_bus,
pid_t thread,
int nice_level);
int pw_rtkit_make_high_priority (struct pw_rtkit_bus *system_bus,
pid_t thread,
int nice_level);
/* Return the maximum value of realtime priority available. Realtime requests
* above this value will fail. A negative value is an errno style error code.
*/
int pinos_rtkit_get_max_realtime_priority (PinosRTKitBus *system_bus);
int pw_rtkit_get_max_realtime_priority (struct pw_rtkit_bus *system_bus);
/* Retreive the minimum value of nice level available. High prio requests
* below this value will fail. The returned value is a negative errno
* style error code, or 0 on success.*/
int pinos_rtkit_get_min_nice_level (PinosRTKitBus *system_bus,
int *min_nice_level);
int pw_rtkit_get_min_nice_level (struct pw_rtkit_bus *system_bus,
int *min_nice_level);
/* Return the maximum value of RLIMIT_RTTIME to set before attempting a
* realtime request. A negative value is an errno style error code.
*/
long long pinos_rtkit_get_rttime_usec_max (PinosRTKitBus *system_bus);
long long pw_rtkit_get_rttime_usec_max (struct pw_rtkit_bus *system_bus);
#ifdef __cplusplus
}
#endif
#endif /* __PINOS_RTKIT_H__ */
#endif /* __PIPEWIRE_RTKIT_H__ */

Some files were not shown because too many files have changed in this diff Show more