mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-07-21 02:05:38 +00:00
doc: internal/protocol: explain registry generation and protocol footers
This commit is contained in:
parent
ffa52fdbc1
commit
53601d44a6
|
@ -7,7 +7,9 @@ The reference implementation uses unix sockets and is implemented in
|
||||||
|
|
||||||
We document the messages here.
|
We document the messages here.
|
||||||
|
|
||||||
# Message header
|
\tableofcontents
|
||||||
|
|
||||||
|
# Message header {#native-protocol-message-header}
|
||||||
|
|
||||||
Each message on the unix socket contains a 16 bytes header and a
|
Each message on the unix socket contains a 16 bytes header and a
|
||||||
variable length payload size:
|
variable length payload size:
|
||||||
|
@ -54,7 +56,7 @@ The payload is a single POD see \ref page_spa_pod for details.
|
||||||
|
|
||||||
After the payload, there is an optional footer POD object.
|
After the payload, there is an optional footer POD object.
|
||||||
|
|
||||||
# Making a connection
|
# Making a connection {#native-protocol-making-connection}
|
||||||
|
|
||||||
First a connection is made to a unix domain socket. By default, the socket is
|
First a connection is made to a unix domain socket. By default, the socket is
|
||||||
named as "pipewire-0" and searched in the following directories:
|
named as "pipewire-0" and searched in the following directories:
|
||||||
|
@ -106,7 +108,7 @@ The client then sends client properties to the server.
|
||||||
This completes the setup of the client. The newly connected client will
|
This completes the setup of the client. The newly connected client will
|
||||||
appear in the registry at this point.
|
appear in the registry at this point.
|
||||||
|
|
||||||
# Core proxy/resource
|
# Core proxy/resource {#native-protocol-core}
|
||||||
|
|
||||||
The core is always the object with Id 0.
|
The core is always the object with Id 0.
|
||||||
|
|
||||||
|
@ -444,7 +446,7 @@ registry.
|
||||||
- global_id: the global_id as it will appear in the registry.
|
- global_id: the global_id as it will appear in the registry.
|
||||||
- props: the properties of the global
|
- props: the properties of the global
|
||||||
|
|
||||||
# Registry proxy/resource
|
# Registry proxy/resource {#native-protocol-registry}
|
||||||
|
|
||||||
The registry is obtained with the GetRegistry method on the Core object.
|
The registry is obtained with the GetRegistry method on the Core object.
|
||||||
The Id depends on the new_id that was provided.
|
The Id depends on the new_id that was provided.
|
||||||
|
@ -522,7 +524,7 @@ A global with id was removed
|
||||||
|
|
||||||
- id: the global id that was removed.
|
- id: the global id that was removed.
|
||||||
|
|
||||||
# PipeWire:Interface:Client
|
# PipeWire:Interface:Client {#native-protocol-client}
|
||||||
|
|
||||||
The client object represents a client connect to the PipeWire server.
|
The client object represents a client connect to the PipeWire server.
|
||||||
Permissions of the client can be managed.
|
Permissions of the client can be managed.
|
||||||
|
@ -638,7 +640,7 @@ Emitted as the reply of the GetPermissions method.
|
||||||
- id: the global id of the object
|
- id: the global id of the object
|
||||||
- permissions: the permission for the given id
|
- permissions: the permission for the given id
|
||||||
|
|
||||||
# PipeWire:Interface:Device
|
# PipeWire:Interface:Device {#native-protocol-device}
|
||||||
|
|
||||||
A device is an object that manages other devices or nodes.
|
A device is an object that manages other devices or nodes.
|
||||||
|
|
||||||
|
@ -745,7 +747,7 @@ Emitted as a result of EnumParams or SubscribeParams.
|
||||||
- param: the parameter. The object type depends on the id
|
- param: the parameter. The object type depends on the id
|
||||||
|
|
||||||
|
|
||||||
# PipeWire:Interface:Factory
|
# PipeWire:Interface:Factory {#native-protocol-factory}
|
||||||
|
|
||||||
A factory is an object that allows one to create new objects.
|
A factory is an object that allows one to create new objects.
|
||||||
|
|
||||||
|
@ -781,7 +783,7 @@ Info is emitted when binding to the factory global or when the information chang
|
||||||
- props: optional properties of the factory, valid when change_mask is (1<<0)
|
- props: optional properties of the factory, valid when change_mask is (1<<0)
|
||||||
|
|
||||||
|
|
||||||
# PipeWire:Interface:Link
|
# PipeWire:Interface:Link {#native-protocol-link}
|
||||||
|
|
||||||
A link is a connection between 2 ports.
|
A link is a connection between 2 ports.
|
||||||
|
|
||||||
|
@ -827,7 +829,7 @@ Info is emitted when binding to the link global or when the information changed.
|
||||||
- props: optional properties of the link, valid when change_mask is (1<<2)
|
- props: optional properties of the link, valid when change_mask is (1<<2)
|
||||||
|
|
||||||
|
|
||||||
# PipeWire:Interface:Module
|
# PipeWire:Interface:Module {#native-protocol-module}
|
||||||
|
|
||||||
A Module provides dynamically loaded functionality
|
A Module provides dynamically loaded functionality
|
||||||
|
|
||||||
|
@ -864,7 +866,7 @@ Info is emitted when binding to the module global or when the information change
|
||||||
- props: optional properties of the module, valid when change_mask has (1<<0)
|
- props: optional properties of the module, valid when change_mask has (1<<0)
|
||||||
|
|
||||||
|
|
||||||
# PipeWire:Interface:Node
|
# PipeWire:Interface:Node {#native-protocol-node}
|
||||||
|
|
||||||
A Node is a processing element in the graph
|
A Node is a processing element in the graph
|
||||||
|
|
||||||
|
@ -991,7 +993,7 @@ Emitted as a result of EnumParams or SubscribeParams.
|
||||||
- param: the parameter. The object type depends on the id
|
- param: the parameter. The object type depends on the id
|
||||||
|
|
||||||
|
|
||||||
# PipeWire:Interface:Port
|
# PipeWire:Interface:Port {#native-protocol-port}
|
||||||
|
|
||||||
A port is part of a node and allows links with other ports.
|
A port is part of a node and allows links with other ports.
|
||||||
|
|
||||||
|
@ -1080,7 +1082,7 @@ Emitted as a result of EnumParams or SubscribeParams.
|
||||||
- next: the index of the next parameter
|
- next: the index of the next parameter
|
||||||
|
|
||||||
|
|
||||||
# PipeWire:Interface:ClientNode
|
# PipeWire:Interface:ClientNode {#native-protocol-clientnode}
|
||||||
|
|
||||||
The ClientNode object is created from the `client-node` factory that is provided
|
The ClientNode object is created from the `client-node` factory that is provided
|
||||||
by the `libpipewire-module-client-node` module.
|
by the `libpipewire-module-client-node` module.
|
||||||
|
@ -1497,7 +1499,7 @@ ports of a node.
|
||||||
- peer_id: the id of the peer port
|
- peer_id: the id of the peer port
|
||||||
- props: optional properties
|
- props: optional properties
|
||||||
|
|
||||||
# PipeWire:Interface:Metadata
|
# PipeWire:Interface:Metadata {#native-protocol-metadata}
|
||||||
|
|
||||||
Metadata is a shared database of settings and properties.
|
Metadata is a shared database of settings and properties.
|
||||||
|
|
||||||
|
@ -1550,7 +1552,7 @@ A metadata key changed. This is also emitted when binding to the metadata.
|
||||||
- type: an optional type
|
- type: an optional type
|
||||||
- value: a value
|
- value: a value
|
||||||
|
|
||||||
# PipeWire:Interface:Profiler
|
# PipeWire:Interface:Profiler {#native-protocol-profiler}
|
||||||
|
|
||||||
The profiler object allows one to receive profiler information of the pipewire
|
The profiler object allows one to receive profiler information of the pipewire
|
||||||
graph.
|
graph.
|
||||||
|
@ -1570,4 +1572,120 @@ The profiler has no methods
|
||||||
```
|
```
|
||||||
- object: a SPA_TYPE_OBJECT_Profiler object. See enum spa_profiler
|
- object: a SPA_TYPE_OBJECT_Profiler object. See enum spa_profiler
|
||||||
|
|
||||||
|
|
||||||
|
# Footer {#native-protocol-footer}
|
||||||
|
|
||||||
|
The message footer contains additional messages, not directed to the
|
||||||
|
destination object defined by the `Id` field.
|
||||||
|
|
||||||
|
The footer consists of a single POD, immediately following the payload
|
||||||
|
POD. The footer POD consists of a sequence of footer opcode Ids and
|
||||||
|
footer payload Structs containing their arguments:
|
||||||
|
|
||||||
|
```
|
||||||
|
Struct(
|
||||||
|
Id: opcode1,
|
||||||
|
Struct { ... },
|
||||||
|
Id: opcode2,
|
||||||
|
Struct { ... },
|
||||||
|
...
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The footer opcodes are separate for server-to-client (`core`) and
|
||||||
|
client-to-server (`client`) directions.
|
||||||
|
|
||||||
|
The message footer is processed before other parts of the message,
|
||||||
|
including the object Id lookup.
|
||||||
|
|
||||||
|
## Core Generation (Footer Opcode 0)
|
||||||
|
|
||||||
|
```
|
||||||
|
Struct(
|
||||||
|
Long: registry_generation,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Indicates to the client what is the current registry generation
|
||||||
|
number of the \ref pw_context on the server side.
|
||||||
|
|
||||||
|
The server shall include this footer in the next message it sends that
|
||||||
|
follows the increment of the registry generation number.
|
||||||
|
|
||||||
|
\see \ref native-protocol-registry-generation
|
||||||
|
|
||||||
|
## Client Generation (Footer Opcode 0)
|
||||||
|
|
||||||
|
```
|
||||||
|
Struct(
|
||||||
|
Long: client_generation,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Indicates to the server what is the last registry generation number
|
||||||
|
the client has processed.
|
||||||
|
|
||||||
|
The client shall include this footer in the next message it sends,
|
||||||
|
after it has processed an incoming message whose footer includes a
|
||||||
|
registry generation update.
|
||||||
|
|
||||||
|
\see \ref native-protocol-registry-generation
|
||||||
|
|
||||||
|
# Registry generation {#native-protocol-registry-generation}
|
||||||
|
|
||||||
|
The registry generation is a 64-bit integer in the PipeWire server
|
||||||
|
\ref pw_context that increments by one when the server allocates a new
|
||||||
|
global \ref PW_KEY_OBJECT_ID for an object.
|
||||||
|
|
||||||
|
The server keeps track of each global *id* as a tuple ( *id*, *object
|
||||||
|
generation* ) where *object generation* is the registry generation
|
||||||
|
value when the *id* was allocated.
|
||||||
|
|
||||||
|
When an object is destroyed, its *id* value may be reallocated to a
|
||||||
|
different object. Because the protocol is asynchronous, the
|
||||||
|
object *id* alone is not sufficient to uniquely identify objects.
|
||||||
|
|
||||||
|
The server looks up objects based on a tuple ( *id*, *generation* ) as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
1. Look up the \ref pw_global based on the *id*.
|
||||||
|
|
||||||
|
2. The lookup fails if there is no global for the *id*, or
|
||||||
|
if *generation* < *object generation*.
|
||||||
|
|
||||||
|
The protocol message generally contains only the object *id*. The
|
||||||
|
registry generation part is passed around as follows:
|
||||||
|
|
||||||
|
1. The server sends the current *registry generation* to clients in the
|
||||||
|
protocol footer, if it has changed.
|
||||||
|
|
||||||
|
2. The clients keep track of the latest registry generation of the
|
||||||
|
messages they have processed. This is the *client generation*.
|
||||||
|
|
||||||
|
3. Each client sends their *client generation* in the protocol footer
|
||||||
|
of the next message to the server, if its value has changed.
|
||||||
|
|
||||||
|
4. The server keeps track for each client the *client generation* they
|
||||||
|
have sent back.
|
||||||
|
|
||||||
|
5. In each protocol message received from client, the server considers
|
||||||
|
each object *id* as tuple ( *id*, *client generation* ).
|
||||||
|
|
||||||
|
This allows the server to know if the object *id* the client refers to was
|
||||||
|
already destroyed, but the client has not yet processed the message
|
||||||
|
indicating that the *id* is gone. The server indicates failed lookups
|
||||||
|
of this type with error code ESTALE to the client.
|
||||||
|
|
||||||
|
If a client has not sent any *client generation* updates to the
|
||||||
|
server, then the server will not do any registry generation checks in
|
||||||
|
object lookups. This is for backward compatibility only.
|
||||||
|
|
||||||
|
The registry generation is an internal detail of the server
|
||||||
|
implementation and the native protocol, and is not visible to clients
|
||||||
|
in the PipeWire API. To identify objects uniquely, clients can use
|
||||||
|
\ref PW_KEY_OBJECT_SERIAL, which are unique for objects and not
|
||||||
|
reused, unlike \ref PW_KEY_OBJECT_ID
|
||||||
|
|
||||||
|
\see \ref PW_KEY_OBJECT_SERIAL
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue