mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-13 08:56:39 -05:00
pinos -> pipewire
This commit is contained in:
parent
f12a5ffc80
commit
83964cec87
197 changed files with 9430 additions and 11744 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -7,5 +7,4 @@ ABOUT-NLS
|
|||
*.tar.xz
|
||||
*.o
|
||||
config.h.meson
|
||||
pkgconfig/libpinos-*.pc
|
||||
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
6
Makefile
6
Makefile
|
|
@ -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
2
NEWS
|
|
@ -1 +1 @@
|
|||
Pinos 0.1
|
||||
PipeWire 0.1
|
||||
|
|
|
|||
17
README
17
README
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
1
doc/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
|||
org-pinos-*.xml
|
||||
|
|
@ -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
8
man/.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <@PACKAGE_BUGREPORT@>; Pinos is available from <url href="@PACKAGE_URL@"/></p>
|
||||
<p>The PipeWire Developers <@PACKAGE_BUGREPORT@>; 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>
|
||||
|
||||
|
|
@ -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 <@PACKAGE_BUGREPORT@>; Pinos is available from <url href="@PACKAGE_URL@"/></p>
|
||||
<p>The PipeWire Developers <@PACKAGE_BUGREPORT@>; 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>
|
||||
|
||||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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)*>
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
58
meson.build
58
meson.build
|
|
@ -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
3
pinos/.gitignore
vendored
|
|
@ -1,3 +0,0 @@
|
|||
pinos
|
||||
test-client
|
||||
pinos-monitor
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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 = {
|
||||
®istry_event_global,
|
||||
®istry_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 = ®istry_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);
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
1
pinos/daemon/.gitignore
vendored
1
pinos/daemon/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
|||
pinos.desktop
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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],
|
||||
)
|
||||
|
|
@ -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
|
||||
2
pinos/dbus/.gitignore
vendored
2
pinos/dbus/.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
|||
org-pinos.c
|
||||
org-pinos.h
|
||||
|
|
@ -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@'],
|
||||
)
|
||||
|
|
@ -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>
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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')),
|
||||
)
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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],
|
||||
)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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],
|
||||
)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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],
|
||||
)
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
executable('pinos-monitor',
|
||||
'pinos-monitor.c',
|
||||
install: true,
|
||||
dependencies : [pinos_dep],
|
||||
)
|
||||
|
|
@ -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
0
pipewire/.gitignore
vendored
Normal 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__ */
|
||||
|
|
@ -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);
|
||||
67
pipewire/client/connection.h
Normal file
67
pipewire/client/connection.h
Normal 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
878
pipewire/client/context.c
Normal 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 = {
|
||||
®istry_event_global,
|
||||
®istry_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 = ®istry_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
115
pipewire/client/context.h
Normal 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__ */
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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);
|
||||
}
|
||||
340
pipewire/client/introspect.h
Normal file
340
pipewire/client/introspect.h
Normal 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__ */
|
||||
|
|
@ -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
90
pipewire/client/log.h
Normal 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__ */
|
||||
|
|
@ -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
76
pipewire/client/loop.h
Normal 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
151
pipewire/client/map.h
Normal 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__ */
|
||||
|
|
@ -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;
|
||||
|
|
@ -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)
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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
|
||||
|
|
@ -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
157
pipewire/client/pipewire.c
Normal 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;
|
||||
}
|
||||
60
pipewire/client/pipewire.h
Normal file
60
pipewire/client/pipewire.h
Normal 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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
57
pipewire/client/properties.h
Normal file
57
pipewire/client/properties.h
Normal 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__ */
|
||||
|
|
@ -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 = {
|
||||
®istry_marshal_bind
|
||||
};
|
||||
|
||||
static const PinosDemarshalFunc pinos_protocol_native_client_registry_demarshal[] = {
|
||||
static const demarshal_func_t pw_protocol_native_client_registry_demarshal[] = {
|
||||
®istry_demarshal_global,
|
||||
®istry_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;
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue