Commit graph

332 commits

Author SHA1 Message Date
Robert Mader
adead74e8c gst: src: Indentation fix
Fixes: f400ff205 (gst: Check for video/ caps before parsing for info)
2024-05-29 18:52:06 +02:00
George Kiagiadakis
68711290bd gst: sink: post an element error when all buffers are removed abruptly
When the link on the pipewire side is destroyed, on video streams, buffers
are removed abruptly and there is no way this pipeline can be revived,
so let's post an element error to stop it.

On a normal shutdown, the pool is first set to flushing in change_state(),
so checking for the flushing state is a good indicator to know if this
is a normal shutdown or not.

See #1980
2024-05-29 10:39:31 +03:00
George Kiagiadakis
ef5f5d4c3c gst: pool: remove unused variable of unknown type 2024-05-29 10:39:31 +03:00
George Kiagiadakis
0b7a62ae02 gst: sink: improve debug messages related to buffer management 2024-05-29 10:39:31 +03:00
George Kiagiadakis
1e2618f314 gst: pool: add explicit remove_buffer method
This is for readability and better control.
Make sure we clear out all pointers to anything related to the released
pw_buffer, including all the memories.
2024-05-29 10:39:31 +03:00
George Kiagiadakis
40fd2553ea gst: pipewirepool: remove dead code 2024-05-29 10:39:31 +03:00
Arun Raghavan
315dc7cdad gst: sink: Fix some object-less debug messages
We have the object, so there's no reason to skip that in the logs.
2024-05-28 13:47:30 +03:00
Arun Raghavan
1e3797512a gst/src: Check for 0 framerate before setting duration
This is possible if the source doesn't provide the framerate (as is the
case for libcamera), or if the framerate is variable (0/1).
2024-05-28 13:47:30 +03:00
Arun Raghavan
3cc5ca5a91 gst/src: Set buffer duration
We compute this from the clock quantum for audio and the negotiated
framerate for video.

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1438
2024-05-28 08:18:47 +00:00
Arun Raghavan
f400ff2050 gst: Check for video/ caps before parsing for info
The gst_video_info_from_caps() API isn't really intended to be used as a
check-for-videoness function (it generates an error-level GStreamer
debug message when used this way).

We check the caps for a video/ name for this reason, which is
functionally equivalent.
2024-05-27 16:01:24 +03:00
Barnabás Pőcze
2bc5d0914d gst: fix stream params memory leak
Both the GPtrArray and its contents are leaked in case of success.
`pw_stream_connect()` copies the params as needed, so use `g_autoptr()`
to free the array and with it, its contents.
2024-05-03 07:15:19 +00:00
Wim Taymans
3e760ea7d7 gst: handle some more errors
The threadloop might fail to create because of missing plugins, so
handle that.

The context might fail to create because of some fatal config error or
missing plugin, handle that too instead of crashing.

See #3994
2024-05-01 20:31:39 +02:00
Robert Rosengren
95127d8a18 gst/src: fix crash when current_caps is NULL
gst_pad_get_current_caps may return NULL and passing that into
gst_caps_is_equal may result in fatal critical log due to the
"g_return_val_if_fail (GST_IS_CAPS (caps1)" check. Fix by checking for
NULL to avoid this.
2024-04-10 09:17:14 +00:00
Wim Taymans
c534acac46 spa: handle empty values better
Make sure the properties are not empty before trying to access them.
2024-04-10 11:08:40 +02:00
Robert Mader
e2e8cf7944 gst/src: Avoid unnecessary renegotiations during streaming
Some clients like many camera apps, including Cheese or Snapshot,
trigger a lot of unnessecary renegotiations. While arguably that should
be solved on a Gstreamer level, we can help out by checking if the
preferred new caps are the same that are already in use and skip the
renegotiation in this case.

This allows several apps to e.g. take pictures without a slow and heavy
stream restart.
2024-03-31 11:03:13 +00:00
Robert Mader
594e3fa09f gst/src: Cleanups for src_negotiate()
Using `g_autoptr` and related modern helpers more often makes
the code smaller, easier to follow and maintain.
No behavior changes intended.
2024-03-31 11:03:13 +00:00
Robert Mader
cc0f7596d6 gst: Always use Choice-pod for modifiers
In order to follow the documentation more closely. Also restructure the
code a bit to make it easier to follow.

See also: e3227b2b5 (gst: simplify modifier extraction)

Fixes: f1b75fc6f (gst: Add support for DMA_DRM / explicit modifiers)
2024-03-28 18:45:13 +01:00
Wim Taymans
e3227b2b5d gst: simplify modifier extraction
spa_pod_get_values() handles both single values and Choice values and
turns the single value into a None choice.

Check that we have a None or Enum choice because we don't handle
anything else.

See !1952
2024-03-28 16:09:18 +01:00
Robert Mader
8848c7e792 gst: Re-enable handling of single long modifiers
A peer may announce support for a single modifier, in which case it may
not use a choice-pod. And while the documentation in `dma-buf.dox`
requires modifiers to always be announced as `SPA_CHOICE_Enum`, this has
been supported in the past - as well as matching Pipewire conventions.

Thus, in order to not break existing clients not crash, reintroduce
handling of modifiers as a single long.

Fixes: f1b75fc6f (gst: Add support for DMA_DRM / explicit modifiers)

Solution suggested by Barnabás Pőcze <pobrn@protonmail.com>
2024-03-28 15:09:34 +01:00
Wim Taymans
2c0d73ab49 gst: handle latency in the pipewiresrc
Get the delay in the graph and subtract this from the cycle start time
to get the timestamp of the buffer.

Report this latency as well.

Fixes #30
2024-03-15 17:31:43 +01:00
Wim Taymans
1fe498560b gst: refactor some of the param handling
Clear the caps when the param is NULL.
2024-03-15 17:31:05 +01:00
Wim Taymans
2bd85e08cf gst: parse the audio rate from caps
Parse the audio rate from the caps and set this as the stream node.rate
property. This will try to switch the graph to this rate and avoids
resampling.

Rework some of the property handling.
2024-03-15 17:27:32 +01:00
Wim Taymans
a69e2ecda5 gst: fall back to buffer time when no header
This at least sets some form of timestamp on the buffers.
2024-03-15 12:10:40 +01:00
Wim Taymans
e86a68db3f gst: add a clock to gst pipewiresink 2024-03-12 17:36:50 +01:00
Wim Taymans
4437f6e000 gst: only remove port once
The port has node_data set/cleared when it is added/removed to/from
the node. Make sure we only remove the port once to avoid a valgrind
error.
2024-03-12 16:54:50 +01:00
Robert Mader
1a6bb994a5 gst: Fix sanitization of non-writable caps
`gst_caps_make_writable()` may create a copy which we have to keep
using afterwards. The return value was meant to be used for that,
but was promptly forgotten for the initial user.
Avoid such errors in the future by using an in-out parameter instead.

While on it, add a type check and remove a check for an impossible
condition.

Fixes: 8a271a87b ("gst: Sanitize caps before translating")
2024-03-07 17:16:18 +00:00
Antonio Larrosa
2df931483d Specify "Audio" in gstreamer sink/src metadata to fix autodetect
gst-play uses autoaudiosink by default when playing audio, which
iterates over all sinks sorting them by rank. By default,
pipewiresink sets the rank to 0, but it can be overridden
by setting the GST_PLUGIN_FEATURE_RANK env. var. like this:

`GST_PLUGIN_FEATURE_RANK=pipewiresink:268 gst-play-1.0  /usr/share/sounds/alsa/test.wav`

But that doesn't work either because the autoaudiosink plugin also
filters the available options, testing for "Sink" and "Audio" to
appear in the classification metadata

(in the strstr comparison in
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/subprojects/gst-plugins-good/gst/autodetect/gstautodetect.c?ref_type=heads#L220
klass is what's set by pipewire as classification,
self->type_klass is "Sink" and self->media_klass is "Audio")

Just adding the word Audio to the classification metadata fixes
this and allows pipewiresink to be selected by autoaudiosink.

I also set it in the source plugin since looking at the code,
autoaudiosrc works exactly the same.
2024-03-07 17:15:20 +00:00
Robert Mader
8a271a87b7 gst: Sanitize caps before translating
DMABuf caps without concrete formats and modifiers don't map well to the
Pipewire negotiation process.
Introduce a new gst_caps_sanitize() helper function, where such cases
can be handled.
2024-03-05 12:08:32 +01:00
Robert Mader
f1b75fc6f8 gst: Add support for DMA_DRM / explicit modifiers
Gstreamer 1.24 added and largely switched to a new, modifier aware
DMABuf API. Unfortunately that breaks the existing DMABuf support in the
PW Gst element.

Add support for the new API.
2024-03-05 12:08:32 +01:00
Wim Taymans
f4e391dd41 stream: add pw_stream_get_nsec() to get current time
Make a method to get the current time to compare agains the pw_time-now
field. This is currently CLOCK_MONOTONIC but make this into a method
so that we can more easily change it later.
2024-03-04 12:59:26 +01:00
Wim Taymans
0f14cc3b13 gst: remove timeouts when autoconnect=false
When we disable autoconnect, disable the timeouts as well. Otherwise the
user has to connect the stream within the 30 second timeout or get a
failure. With autoconnect we can reasonably assume there is a problem
when the stream is not connected after 30 seconds.

Fixes #3884
2024-03-01 10:29:18 +01:00
George Kiagiadakis
5a130ddd73 gstpipewiresrc: break out of wait_started() also on STATE_UNCONNECTED
When the session manager sends an error to the client, it typically
also destroys the node after the error, which causes the stream to go
to STATE_UNCONNECTED via proxy_removed(). In that case, make sure
we exit the loop early, otherwise it will take 30 seconds to unblock
gst_element_set_state()

This is a revised version of the fix that was commited via !1763
and then reverted, as it was problematic. Now the code ensures
that it breaks out only if the state was previously CONNECTING
or higher.
2023-12-26 16:01:44 +00:00
Michael Tretter
03173530da gst/pipewiresink: fix dts_offset
GStreamer uses a time stamp for the decoding time, but PipeWire uses an
offset to the presentation time. Thus, the pipewiresink must not use the
DTS as dts_offset, but has to calculate the offset.

If the buffer's DTS is invalid, assume that dts is pts.
2023-12-21 15:11:56 +01:00
Wim Taymans
ecf4b071e5 gst: keep track of node ports
Keep a list of ports for the node. When the node goes away, clear the
port links to the node. Handle the case where the port no longer has a
node.

This avoids a crash when, for example, the node permission is removed
and the port points to the now freed node_data.

Fixes #3708
2023-12-14 13:00:00 +01:00
Wim Taymans
5eb1f35997 gst: remove unused pending list 2023-12-14 12:59:04 +01:00
Michael Tretter
6a68c87b19 gst/pipewiresink: remove special case for size 0
There is no need for a special case with size 0. If size is 0, we can
also write the size instead of 0 to the buffer.
2023-12-05 14:44:56 +00:00
Michael Tretter
0bda84bca1 gst/pipewiresink: replace tabs with spaces
Tabs and spaces are mixed for indentation in the pipewiresink. Replace
all tabs with 8 spaces although indentation is 2 spaces, since that
looks like the intended indent.
2023-12-05 14:44:56 +00:00
Michael Tretter
49b971b5b1 gst/pipewirepool: change acquire/release to log messages
The messages are printed for every buffer. Therefore, they should be log
messages. Also add the bufferpool to the message to be able to identify
the bufferpool that handles the buffers.
2023-12-05 14:44:56 +00:00
Michael Tretter
5f916d8a2d gst/pipewirepool: print buffer type as debug message
The buffers are added to the pipewirepool during setup. Therefore, they
should be debug messages. As at it, use the debug helper to print the
string of the buffer type.
2023-12-05 14:44:56 +00:00
Wim Taymans
aef99f840f Revert "gstpipewiresrc: break out of wait_started() also on STATE_UNCONNECTED"
This reverts commit 7465175ad0.

wait_started() is called before the stream is connecting and so
exits with an error immediately, which then makes the stream start
too early and block.
2023-11-16 09:51:11 +01:00
George Kiagiadakis
7465175ad0 gstpipewiresrc: break out of wait_started() also on STATE_UNCONNECTED
When the session manager sends an error to the client, it typically
also destroys the node after the error, which causes the stream to go
to STATE_UNCONNECTED via proxy_removed(). In that case, make sure
we exit the loop early, otherwise it will take 30 seconds to unblock
gst_element_set_state()
2023-11-09 20:59:40 +00:00
George Kiagiadakis
a852b979b6 gst: avoid reporting error twice
First, make the error permanent by calling pw_stream_set_error()
and when this emits an error state again, report that to GStreamer.

Do the same in pipewiresink, which didn't even have the
pw_stream_set_error() call before, so the stream wasn't really going
into an error state at all.
2023-11-09 20:59:40 +00:00
Wim Taymans
bdb7f3adc8 gst: don't stop streaming when paused
We pause when we are unlinked, don't stop the streaming thread because
then we won't be able to resume when we are linked again.

Fixes #3620
2023-11-02 10:06:03 +01:00
Michael Tretter
e4def0ce18 pipewiresink: use maximum size of buffers to configure pool
For encoded formats, buffer size is the size of the actual data in the
buffer and may change for each frame depending on the content. Thus,
configuring the buffer pool of the pipewiresrc with the size of the
first buffer may be insufficient for later buffers.

Configure the buffer pool to the maximum size of the first upstream
buffer and assume that the following buffers will be allocated with the
same size as the first buffer.
2023-10-27 18:01:37 +02:00
Michael Tretter
efa08e9892 gst: update buffer size only if format defines a size
For encoded formats, p->video_info.size will be 0. If the pipewiresrc
handles an encoded format, the bufferpool will be configured to allocate
buffers of size 0. This will cause errors later when trying to copy the
frames into the pipewire buffers.

Update the bufferpool size only if video_info defines an actual buffer
size.
2023-10-27 18:01:37 +02:00
Michael Tretter
bd15e5275b pipewiresink: copy metadata into pipewirepool buffers
If the pipewiresink needs to copy the GStreamer buffers to the PipeWire
buffers, because the upstream element didn't use the pipewirepool, the
metadata must be copied, too. Otherwise the pipewire datas will be
filled with the metadata from the buffer during the initialization and
not the currently used buffer.

For example, without copying the metadata the buffer timestamp will be
missing on the pipewire buffers.
2023-10-27 18:00:51 +02:00
Michael Tretter
9a72766ae8 pipewiresink: fix type of SPA_META
The SPA_PARAM_META_type must be configured as a SPA_POD_Id, not as
SPA_POD_Int. Otherwise, PipeWire won't allocate the metas.
2023-10-27 17:44:32 +02:00
Wim Taymans
3eed0fbe9b gst: mark streams async
From the process callback we signal a cond and don't dequeue/queue
a buffer directly.
2023-10-21 09:42:15 +02:00
Philippe Normand
140374d207 gst: Prevent a crash when stopping device provider
The provider might fail to connect to the PipeWire core when starting up, so
when stopping we need to check the core is valid before attempting to acquire a
mutex on its loop.
2023-08-04 10:01:07 +01:00
Wim Taymans
b0a7e4a267 gst: lock/unlock around proxy destroy
See #3324
2023-07-04 12:04:29 +02:00