diff options
Diffstat (limited to 'doc/pipewire-library.dox')
-rw-r--r-- | doc/pipewire-library.dox | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/doc/pipewire-library.dox b/doc/pipewire-library.dox new file mode 100644 index 0000000..cecb930 --- /dev/null +++ b/doc/pipewire-library.dox @@ -0,0 +1,240 @@ +/** \page page_library PipeWire Library + +There are two main components that make up the PipeWire library: + +1. An implementation of a graph based media processing engine. +2. An asynchronous IPC mechanism to manipulate and introspect + a graph in another process. + +There is usually a daemon that implements the global graph and +clients that operate on this graph. + +The IPC mechanism in PipeWire is inspired by Wayland in that it +follows the same design principles of objects and methods/events +along with how this API is presented to the user. + +PipeWire has a plugin architecture that allows new features to +be added (or removed) by the user. Plugins can hook into many +aspects of PipeWire and change the behaviour or number of +features dynamically. + + +# Principles + +The PipeWire API is an object oriented asynchronous protocol. +All requests and replies are method invocations on some object. + +Objects are identified with a unique ID. Each object implements an +interface and requests result in invocations of methods on the +interface. + +The protocol is message based. A message sent by a client to the +server is called a method. A message from the server to the client +is called an event. Unlike Wayland, these messages are not (yet) +described in an external protocol file but implemented directly in +a protocol plugin. Protocol plugins can be added to add new +objects or even protocols when required. + +Messages are encoded with \ref page_spa_pod, which make it +possible to encode complex objects with right types. + +Events from the server can be a reply to a method or can be emitted +when the server state changes. + +Upon connecting to a server, it will broadcast its state. Clients +should listen for these state changes and cache them. There is no +need (or mechanism) to query the state of the server. + +The server also has a registry object that, when listening to, +will broadcast the presence of global objects and any changes in +their state. + +State about objects can be obtained by binding to them and listening +for state changes. + + +# Versioning + +All interfaces have a version number. The maximum supported version +number of an interface is advertized in the registry global event. + +A client asks for a specific version of an interface when it binds +to them. It is the task of the server to adapt to the version of the +client. + +Interfaces increase their version number when new methods or events +are added. Methods or events should never be removed or changed for +simplicity. + + +# Proxies and Resources + +When a client connects to a PipeWire daemon, a new `struct pw_proxy` +object is created with ID 0. The `struct pw_core` interface is +assigned to the proxy. + +On the server side there is an equivalent `struct pw_resource` with +ID 0. Whenever the client sends a message on the proxy (by calling +a method on the interface of the proxy) it will transparently result +in a callback on the resource with the same ID. + +Likewise if the server sends a message (an event) on a resource, it +will result in an event on the client proxy with the same ID. + +PipeWire will notify a client when a resource ID (and thus also proxy +ID) becomes unused. The client is responsible for destroying the +proxy when it no longer wants to use it. + + +# Interfaces + +## struct pw_loop + +An abstraction for a `poll(2)` loop. It is usually part of one of: + +- `struct pw_main_loop`: A helper that can run and stop a `pw_loop`. +- `struct pw_thread_loop`: A helper that can run and stop a `pw_loop` + in a different thread. It also has some helper + functions for various thread related synchronization + issues. +- `struct pw_data_loop`: A helper that can run and stop a `pw_loop` + in a real-time thread along with some useful helper + functions. + +## struct pw_context + +The main context for PipeWire resources. It keeps track of the mainloop, +loaded modules, the processing graph and proxies to remote PipeWire +instances. + +An application has to select an implementation of a `struct pw_loop` +when creating a context. + +The context has methods to create the various objects you can use to +build a server or client application. + +## struct pw_core + +A proxy to a remote PipeWire instance. This is used to send messages +to a remote PipeWire daemon and to receive events from it. + +A core proxy can be used to receive errors from the remote daemon +or to perform a roundtrip message to flush out pending requests. + +Other core methods and events are used internally for the object +life cycle management. + +## struct pw_registry + +A proxy to a PipeWire registry object. It emits events about the +available objects on the server and can be used to bind to those +objects in order to call methods or receive events from them. + +## struct pw_module + +A proxy to a loadable module. Modules implement functionality such +as provide new objects or policy. + +## struct pw_factory + +A proxy to an object that can create other objects. + +## struct pw_device + +A proxy to a device object. Device objects model a physical hardware +or software device in the system and can create other objects +such as nodes or other devices. + +## struct pw_node + +A Proxy to a processing node in the graph. Nodes can have input and +output ports and the ports can be linked together to form a graph. + +## struct pw_port + +A Proxy to an input or output port of a node. They can be linked +together to form a processing graph. + +## struct pw_link + +A proxy to a link between in output and input port. A link negotiates +a format and buffers between ports. A port can be linked to many other +ports and PipeWire will manage mixing and duplicating the buffers. + + +# High Level Helper Objects + +Some high level objects are implemented to make it easier to interface +with a PipeWire graph. + +## struct pw_filter + +A `struct pw_filter` allows you implement a processing filter that can +be added to a PipeWire graph. It is comparable to a JACK client. + +## struct pw_stream + +A `struct pw_stream` makes it easy to implement a playback or capture +client for the graph. It takes care of format conversion and buffer +sizes. It is comparable to Core Audio AudioQueue or a PulseAudio +stream. + + +# Security + +With the default native protocol, clients connect to PipeWire using +a named socket. This results in a client socket that is used to +send messages. + +For sandboxed clients, it is possible to get the client socket via +other ways, like using the portal. In that case, a portal will +do the connection for the client and then hands the connection socket +to the client. + +All objects in PipeWire have per client permission bits, currently +READ, WRITE, EXECUTE and METADATA. A client can not see an object +unless it has READ permissions. Similarly, a client can only execute +methods on an object when the EXECUTE bit is set and to modify the +state of an object, the client needs WRITE permissions. + +A client (the portal after it makes a connection) can drop permissions +on an object. Once dropped, it can never reacquire the permission. + +Clients with WRITE/EXECUTE permissions on another client can +add and remove permissions for the client at will. + +Clients with MODIFY permissions on another object can set or remove +metadata on that object. + +Clients that need permissions assigned to them can be started in +blocked mode and resume when permissions are assigned to them by +a session manager or portal, for example. + +PipeWire uses memfd (`memfd_create(2)`) or DMA-BUF for sharing media +and data between clients. Clients can thus not look at other clients +data unless they can see the objects and connect to them. + + +# Implementation + +PipeWire also exposes an API to implement the server side objects in +a graph. + + +# Error Reporting + +Functions return either NULL with errno set or a negative int error +code when an error occurs. Error codes are used from the SPA plugin +library on which PipeWire is built. + +Some functions might return asynchronously. The error code for such +functions is positive and SPA_RESULT_IS_ASYNC() will return true. +SPA_RESULT_ASYNC_SEQ() can be used to get the unique sequence number +associated with the async operation. + +The object returning the async result code will have some way to +signal the completion of the async operation (with, for example, a +callback). The sequence number can be used to see which operation +completed. + +*/ |