Commit graph

2351 commits

Author SHA1 Message Date
Wim Taymans
44a1d93b7d stream: improve the docs 2024-09-20 15:52:26 +02:00
Wim Taymans
c07663b236 impl-node: only process RequestProcess after state change
Wait until we are in the RUNNING state before sending
RequestProcess.
2024-09-19 19:12:54 +02:00
Wim Taymans
cd68819feb stream: update state based on node
Follow the state of the node and update the stream state accordingly.

The most important part is that Start is async and so it's better to
wait for completion from the node before emiting the STREAMING state.
2024-09-19 19:12:31 +02:00
Wim Taymans
2301d3000b impl-link: improve debug, add the node async state 2024-09-19 19:01:43 +02:00
Wim Taymans
911a601b95 impl-node: only let the server send RequestProcess commands
When we emit the RequestProcess event from an exported node, don't
send the RequestProcess command to ourselves but let the server
decide where to send it to.
2024-09-17 09:25:58 +02:00
Wim Taymans
ce390d5b22 spa: add spa_json_object_next
This gets the next key and value from an object. This function is better
because it will skip key/value pairs that don't fit in the array to hold
the key.

The previous code patter would stop parsing the object as soon as a key
larger than the available space was found.
2024-09-16 09:50:36 +02:00
Wim Taymans
cd81b5f39a spa: add spa_json_begin_array/object and relaxed versions
Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object

This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
2024-09-16 09:50:33 +02:00
Wim Taymans
b8c6bfae1a stream: Add support for setting ProcessLatency
Pass the ProcessLatency set on the stream to the implementor.
2024-09-10 15:32:00 +02:00
Wim Taymans
0ef30aecab impl-link: silence some debug 2024-09-06 15:08:12 +02:00
Wim Taymans
b57375ba85 stream: enable videoadapter in all cases
It works fine without an explicitly selected converter.
2024-09-06 12:25:20 +02:00
Wim Taymans
1751575fc2 global: avoid recursive destroy calls
Fixes #4250
2024-09-04 18:05:29 +02:00
Wim Taymans
c84cf9a9d4 impl-link: handle errors better
Keep the original sequence number of the port_set_param(Format) and
port_use_buffer() calls around. When they produce an error, we will
get an error with the same sequence number.

When the sync completes, check if we got an error for the pending
operation and return that as the result.

We then also mark the link in error. We don't mark the port in error
because that is not really the case.

This should make the link error when negotiation of format or buffers
fails instead of silently continuing.
2024-09-02 10:04:05 +02:00
Wim Taymans
b5d0532a77 impl-node: improve compatibility with older clients
Clients before version 1 don't update the active_driver_id and so we
must do on the server ourselves or else the node will not be scheduled.
2024-08-21 17:41:13 +02:00
Wim Taymans
1ef6db7d54 impl-node: only increment pending when not async
Place the async state of the node in its activation.

Don't increment the pending state of the driver when an async node is
found because the async nodes will not trigger the driver when they
complete.

See !2104
2024-08-16 22:44:53 +02:00
Barnabás Pőcze
d4de97a473 impl-link: fix error message memory leak
`pw_link_info::error` was previously not cleared when a link was destroyed,
leading to a memory leak if an error message had been set. For example,
if format negotiation fails, and as a result the link is destroyed.
2024-08-13 09:12:48 +00:00
Wim Taymans
89bf8b8566 impl-node: improve driver activation counter calculation
Don't schedule nodes that didn't receive us as the driver node yet
because they will not be able to signal us when they complete and leave
us xrun.

Also only count the nodes that we will actually schedule and expect a
signal from, set this in the pending activation counter. This can be
less when some nodes are still starting or receiving the driver
activation record.

This eleminates some errors when adding and removing nodes.

See #4182
2024-08-08 15:20:38 +02:00
Wim Taymans
338e32e57c impl-node: Do xrun check a bit better
Check if the node is FINISHED instead of checking the refcounts. It's
possible that the refcounts are 0 but the node was not scheduled or
finished yet.

If the node is not FINISHED but TRIGGERED, we can run the recover
without reporting an error.

Any other state is an error and we need to log this and recover.

See #4182
2024-08-08 15:17:27 +02:00
Wim Taymans
cc2c86a55b impl-node: always INACTIVATE a node when stopping
Set the node state INACTIVE on the client and server side in all cases
when stopping to ensure nothing tries to schedule the node anymore.
2024-08-08 15:15:39 +02:00
Wim Taymans
5afdd54277 impl-node: improve debug
Use ATOMIC_LOAD to get status.
Debug the pending state after decrementing so we debug the value we
are actually going to test.
Add node id to debug lines to better track things.
2024-08-08 15:00:07 +02:00
Wim Taymans
8fb05935d3 impl-node: improve xrun debug
Debug the xrun state before we change things and run the recovery
process.
2024-08-08 15:00:07 +02:00
Wim Taymans
3376dff72b impl-node: don't overwrite node state when finished
Don't just overwrite the state with FINISHED but only do this when the
state was AWAKE.

The server might already have started a new cycle and placed
NOT_TRIGGERED as the state. Or, it might have changed the state to
INACTIVE. In all cases, we should not overwrite the state unless it was
AWAKE and we should only trigger peers when we were AWAKE.

This fixes some spurious xruns and glitches.

See #4182
2024-08-08 15:00:07 +02:00
Wim Taymans
8c1a69f1b5 loop: don't usleep when queue is full
When the queue is full, before this patch we used to go into usleep in
the hope that the other thread will run and empty the queue and that we
can retry after the usleep.

This however does not always work because the other thread might be waiting
for the thread that does the invoke call and we lock forever.

Therefore we should always try to make progress in some way. Instead of
waiting, allocate an (or use the previously allocated) overflow queue and
write to that one. We can chain multiple overflow queues together as many
as we need (but we might want to bound that as well).

The loop.retry-timeout property is now deprecated.

See #4114
2024-08-06 12:05:11 +02:00
Wim Taymans
f4b2854770 impl-node: include config.h to define HAVE_MALLOC_TRIM
It was previously not used..
2024-07-30 17:50:04 +02:00
Wim Taymans
5cc7e583e2 impl-node: reset pending state when moving driving node
Commit d04a28daef moved the configuration
of the IO_Position after we removed the node from the old driver but
forgot to move the code that updates the pending_state.

See #4094
2024-07-30 14:17:58 +02:00
Wim Taymans
7f38653589 filter: Use the stream DSP format to negotiate control types
Add OSC and UMP control types and make sure the mixer converts to the
selected format.

Mostly useful for legacy filters that use the old MIDI format, placing
the Midi control type in the format will make the mixer convert to it.
2024-07-30 09:38:18 +02:00
Wim Taymans
bb82b2e493 impl-port: improve IO_Buffers management on ports
Make sure we clear IO_Buffers on the port and mixer before we clear the
buffers or the format. The IO_Buffer is used to check if the port should
be processed or not and its update is synchronized with the data-thread.

Set IO_Buffers on the mixer and node only after we have configured the
buffers on the node.

See #4094
2024-07-29 18:15:09 +02:00
Wim Taymans
db710359ad impl-link: make async link when on e of the nodes is async
We simply cannot schedule async nodes properly if we don't have the
async link. This change was done to make sure that driver sources don't
end up with async buffers and cause a unneccesary 1 cycle delay in
async clients. But we can fix this in a better way, like this:

Increment the cycle counter after we copy the output port buffers. This
ensures the async clients immediately pick up the new buffers (or the
output buffers from the previous cycle).

Also remove some old compatibility code that is no longer useful.

Fixes #4138
See #4133
2024-07-22 13:10:33 +02:00
Wim Taymans
32e4553a05 impl-node: always INACTIVATE when stopping
A remote node is prepared when the Start command sync reply has been
received.

If we however quickly switch from active to inactive, the
pending reply is cancelled but the remote node will have set the
FINISHED status and will be ready to be scheduled.

Make it so that we always set the INACTIVE status when the node is
canceled and unprepared, even if we didn't get the reply and the node
was not prepared.

Fixes #4122
2024-07-18 13:44:36 +02:00
Arun Raghavan
41c30d3564 impl-node: Document timing-related pw_node_activation fields
Should make the meanings of the fields a bit clearer.
2024-07-17 15:54:34 +00:00
Wim Taymans
42096de3cc node: add a clock XRUN_RECOVER flag
Make a new flag that is set when the process function is called because
of a recover from a graph xrun.

Use this flag in the freewheel driver to detect a recover and to avoid
scheduling a new timeout. We should schedule a new timeout only when the
process function was called after completion.

This fixes export in ardour some more when the initial driver timeout
didn't complete (when, for example, some nodes were still starting up).
2024-07-12 12:21:59 +02:00
Wim Taymans
4baa94fce2 thread: make it possible to set a custom create function
Make a property to pass a custom function pointer to create threads
instead of pthread_create.

Use this in jack instead of bypassing the thread utils create function,
which gives the wrong thread rt priority with rtkit.

Fixes #4099
2024-07-09 17:04:35 +02:00
Pauli Virtanen
daef48b0eb conf: fix context.exec args parsing
The 'args' can be either JSON array, or a string.  If a string it should
not be parsed as JSON for a second time, but instead split at
whitespaces.
2024-07-04 20:54:51 +00:00
Wim Taymans
2d0bc982bc impl-node: set INACTIVE state on server
Don't wait for the client to set the INACTIVE state, do it on the
server. We already decremented the target required so we don't want to
schedule the node anymore.

Fixes some xruns when removing nodes in a stress test.
2024-07-03 17:42:39 +02:00
Wim Taymans
59b9da9477 impl-node: disable async for driver nodes
Make it so that a driver node can never be scheduled async. It could
possibly make sense when the driver node is not currently driving the
graph but when it drives the graph it always needs to be sync. This
also simplifies the target activation because we can simply check the
async state and ignore if the node is driving or not.

Also make sure that we never make an async link with a driver output port.
This does not make sense because the driver node will always be
triggered sync first and before the async node so we can simply make
a sync link.

This fixes the modified (only generate 1 buffer) video-src -> video-play
case where the buffer never arrives in video-play because of the
useless async link.

Fixes #4092
2024-07-03 14:49:12 +02:00
Wim Taymans
29171cadb5 context: improve sync group handling some more
Keep track of the sync nodes we added to a driver and bring in the other
nodes from the same sync group, group or link groups. This makes it
possible to have disjoint sync groups each with their own driver.
2024-07-01 16:05:07 +02:00
Wim Taymans
070bcea63b context: Fix node collect with groups and sync enabled
When checking for the nodes to collect with a driver, don't just skip
checking the other nodes when the driver is not in the sync group.
Instead collect all nodes that have the same group and link group as
the driver first and then check the sync groups.

Fixes export in ardour8

Fixes #4083
2024-07-01 14:50:34 +02:00
Wim Taymans
b151b1f570 impl-node: fix required state for async driver nodes
When the node activation.required was incremented because it was a
driver, only decrement it in that case, regardless of the current driver
state of the node.

This fixes the case of KODI where the required field gets out of sync
and things become unschedulable.

Fixes #4087
2024-07-01 10:36:09 +02:00
Wim Taymans
1e5d9cc635 impl-node: increment async driver nodes required field
A driver can't be async, we always need to be able to trigger it
to start it so increment the required field.

Fixes an issue with asunc drivers such as the video-src example or gnome
screen sharing.
2024-06-27 13:22:52 +02:00
Wim Taymans
9d1d1fcbef impl-port: add port.group property
Can be used to group ports together. Mostly because they are all from
the same stream and split into multiple ports by audioconvert/adapter.

Also useful for the alsa sequence to group client ports together.

Also interesting when pw-filter would be able to handle streams in the
future to find out what ports belong to what streams.
2024-06-24 13:38:09 +02:00
Wim Taymans
ea7e0e9152 spa: revert peer_enum_params node event again
It's not used anymore because it does work so well.

The problem is that while it transparently proxies param enums on
ports to peers, it fails to emit events when those peer
params change in a way that would make the enum result change as well.
This makes it quite hard to use this correctly.
2024-06-20 10:22:45 +02:00
Wim Taymans
1ae4374ccf Fix compilation with -Werror=float-conversion
Better make the conversions explicit so that we don't get any surprises.

Fixes #4065
2024-06-18 12:17:56 +02:00
Wim Taymans
50870aac57 impl-node: move node_peer functions to impl-node 2024-06-18 09:49:01 +02:00
Wim Taymans
33f1a713cd impl-node: set active_driver_id
This is the driver id that the client has received and is using right
now. We don't use this yet but it could be used in the future to check
if a client has the most up to date info.
2024-06-18 09:47:33 +02:00
Wim Taymans
a07f73ce82 impl-node: add more backwards compat
Make sure newer clients can work with an older server:

- Add client and server versions in the activation
- On older server, clients needs to trigger peers without CAS of status
- On older server, jack transport is started with command.
- Use client version to know when to set the INACTIVE/FINISHED
  state on the server instead.
- Async clients need to trigger peers on old server.
2024-06-17 12:07:09 +02:00
Wim Taymans
e045ef0e4c impl-node: add compat with old nodes 2024-06-14 12:41:03 +02:00
Wim Taymans
c89a68b0b4 impl-node: handle node <-> driver links with node_peer
Also handle the relation between a node and the driver with pw_node_peer,
like we do with the links.

Because these are refcounted, we only make one peer for a node that is
linked to another node that is also the driver (pw-play -> sink) and we
save some fds as well as some admin stuff and overhead for the refcounts.

This in return then results in less problems getting all the refcounts
right when adding/removing nodes.
2024-06-14 11:52:59 +02:00
Wim Taymans
b7af52e3fb impl-node: partially revert target rework
We can't let a client decrement the required state because if it crashes
or fails to decrement, the graph becomes unschedulable.
2024-06-13 17:40:55 +02:00
Wim Taymans
d04a28daef impl-node: clean up the configuration of the Position io area
Set the new IO Position after we removed the node from the old driver
and before the new driver is going to schedule the node. This makes
a little more sense.
2024-06-12 09:56:57 +02:00
Wim Taymans
c85e7cadf1 impl-node: async driver nodes need to activate targets
When a driver is async it still needs to activate the targets or else no
targets will ever be triggered.

Fixes #4046
2024-06-10 16:32:13 +02:00
Wim Taymans
0d9a959ab6 Revert "context: add loader.rules"
This reverts commit cfeb937443.

Let's remove this for now, the node.rules and device.rules are mostly
used for this. We can add this later when there is a need for it.
2024-06-10 10:34:07 +02:00