Commit graph

342 commits

Author SHA1 Message Date
Michael Tretter
3b581b2417 gst: pipewiresink: print stream state as string
Print the state of the stream not only as the numeric value, but also
print the name of the state to help the reader.

While at it, add the sink element to the log output to be able to
identify the sink that received the state change.
2024-06-19 15:43:06 +00:00
Robert Rosengren
3cbda26f07 gst: src: disable active state when only going to PAUSED
The pipewiresrc starts the stream in active state but should be inactive
if only going to PAUSED state. This patch sets the stream to inactive
when wait_started has returned in the GStreamer state tranistions.

Also resets internal started state when going PAUSED -> READY.

Fixes #4049
2024-06-17 15:11:48 +02:00
Arun Raghavan
9da01413a1 gst: sink: Disable active state setting when going to PAUSED
On first start, the stream is set to be active when connected. However,
when the element is going to PAUSED and not subsequently to PLAYING,
this is incorrect behaviour.

Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4049
2024-06-12 06:58:44 +00:00
Michael Tretter
a9bf5fa24a gst: fix JPEG format
Since commit f400ff2050 ("gst: Check for video/ caps before parsing
for info") JPEG support in the GStreamer elements is broken as JPEG is
not recognized as a video format anymore.

gst_video_info_from_caps is able to handle "video/" and "image/"
formats. Therefore, the check needs to allow "image/" too.

While at it, cleanup the formatting to make the check more readable.
2024-06-12 06:56:03 +00:00
Michael Tretter
3b68b5088b gst: pipewiresrc: move correct brace under HAVE_GSTREAMER_DMA_DRM
The HAVE_GSTREAMER_DMA_DRM belongs to the inner brace, not the outer
brace, since the inner if statement is under HAVE_GSTREAMER_DMA_DRM.

While doesn't make a difference to the compiler, but confuses a reader.

Put the other brace under the HAVE_GSTREAMER_DMA_DRM.
2024-06-12 06:56:03 +00:00
George Kiagiadakis
8da35df0bf gst: use G_DECLARE_FINAL_TYPE for all classes 2024-06-11 12:51:51 +00:00
George Kiagiadakis
0bde0ebad8 gst: reference the GstPipeWireStream from the pool & the clock 2024-06-11 12:51:51 +00:00
George Kiagiadakis
0c40c01477 gst: factor out the stream management and some common variables in a new class
Construct this new class from both the src and sink to be able to share code

Consolidate the previous mess of open/close/start/stop into a single pair
of open/close functions in the new stream class
2024-06-11 12:51:51 +00:00
Robert Mader
e6f2aa6ce0 gst: src: Improve DMA_DRM caps selection
The translation between Pipewire parameters and Gstreamer caps is,
for compatibility reasons, ambiguous. Formats with linear modifier
are translated both in the legacy way as `format`, as well as
`drm-format`.

When finishing negotiation and setting caps, ensure that we:
1. set caps that the peer actually supports in order to prevent
   negotiation errors.
2. fixate caps to DMA_DRM if both options are supported, using the newly
   introduced helper, in order to prevent hangs.

While on it, add some small clean-ups that hopefully make the code
easier to follow, notably that `pwsrc->caps` and `pwsrc->possible_caps`
are only used during negotiation.
2024-05-29 19:29:02 +02:00
Robert Mader
05b1c9d0c8 gst: Add helper to fixate DMA_DRM caps
When support for modifier-aware DMA_DRM formats was added in f1b75fc6,
the translation between Pipewire parameters and Gstreamer caps was kept
compatible with the] non-DMA_DRM/legacy API by reporting format/modifier
combinations with linear or invalid modifier both as `format` and
`drm-format`.

In cases when a linear modifier ends up being negotiated, this, however,
resurts in non-fixated caps, preventing the negotiation to succeed.

Add a helper that allows to fixate such caps.
2024-05-29 19:05:53 +02:00
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