Commit graph

297 commits

Author SHA1 Message Date
Michael Tretter
16964b323f 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.
2024-01-04 17:55:14 +01:00
George Kiagiadakis
0c99d37db2 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.
2024-01-04 17:53:25 +01:00
Wim Taymans
67fde171a2 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:13:56 +01:00
Wim Taymans
705c977e9e gst: remove unused pending list 2023-12-14 13:13:51 +01: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
Wim Taymans
bb72e3bc00 gst: fill default stride in metadata
When there is no metadata on the buffer, use the default video stride
as the stride on the pipewire buffers instead of 0.

Fixes #3236
2023-05-23 09:00:30 +02:00
Robert Mader
004206db37 gst/pipewiresrc: Let GstBaseSrc handle pseudo-live calculations
Let's avoid doing timestamp math as much as possible and let `GstBaseSrc`
do it for us instead.

This bring the source more in line with others in Gstreamer and
may help to avoid bugs and share concepts or code.
2023-04-19 19:22:24 +00:00
Wim Taymans
0962555291 gst: implement renegotiation
If the stream format changes, set the basesrc caps again before pushing
a new buffer.

See #3147
2023-04-14 10:42:01 +02:00
Robert Mader
5fc782b893 pipewireclock: Disable clock_reset() for now
This was introduced in 4faa28fd96 in order to correctly map the time
from the stream. From d52df30c88 on, however, the clock switched to
monotonic time, which does not need the extra-offset.

Disable `clock_reset()` for now but leave it in place so we can easily
reenable it once we use the stream time again.

This fixes video recording in Cheese and similar apps.

Closes https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3149
2023-04-12 10:13:54 +00:00
Robert Mader
8fff69353b gst: deviceprodiver: Sort devices by session priority
Applications using the device provider typically list devices in the
order they were added. In order to ensure that apps pick nodes like cameras
with the highest priority by default, sort devices accordingly.

This unfortunately does not not have an effect on nodes added later,
e.g. on hotplug.

Closes https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3072
2023-03-11 10:55:07 +01:00
Robert Mader
06bad5523d gstpipewiresrc: Set stream error on caps negotiation failure
In order to make `wait_started()` error out accordingly, which otherwise
blocks `change_state()` until the timeout is over.
2023-02-23 11:58:52 +00:00
Robert Mader
0b69f37a7c gstpipewiresrc: Do not alter meta plane count
Shared memory buffers may contain multiple planes.
Thus we need to keep the meta plane number as derived from the format.

Closes https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3045
2023-02-21 08:17:26 +00:00
Mike Playle
23b86761a5 Add autoconnect parameter to pipewiresrc element 2023-02-21 08:16:44 +00:00
Barnabás Pőcze
934ab3036e treewide: use SPDX tags to specify copyright information
SPDX tags make the licensing information easy to understand and clear,
and they are machine parseable.

See https://spdx.dev for more information.
2023-02-16 10:54:48 +00:00
Robert Mader
353c1f709d gstpipewiresrc: make stream errors permanent
When pw_stream receives a proxy error it does not set its state to an
error state on its own, commenting:
```
we just emit the state change here to inform the application.
If this is supposed to be a permanent error, the app should
do a pw_stream_set_error()
```

Until now this was not done in the pipewiresrc, resulting in the
negotiation loop to not bail out after an error as a successive
`pw_stream_get_state()` did not return an error state.

Make the error permanent so negotiation errors make us take the
appropriate error paths.
2023-02-15 14:49:42 +01:00
Huang-Huang Bao
4b60569c4a gst: correct buffer & meta offset calculation
The offset in GstVideoMeta point to location of merge-mapped buffer memories (see "gst_buffer_find_memory()") instead of raw memory location for each plane, make adjustment to comply this rule.

Also some cleanups.

Fixes 023577e391
2023-02-06 06:34:14 +00:00
Huang-Huang Bao
023577e391 gst: add buffer video meta support
Fixes video buffer strides handling.
This enables passing of image datas with right line padding.
2023-02-03 07:23:35 +00:00
Georges Basile Stavracas Neto
0fd44bc9d0 pipewiresrc: Make it live by default
In theory, the pipewiresrc element is a live element by default.
However, that is not reflected in code, as the element never sets
that flag unless explicltly requested through stream properties.

Make it live by default, but still respect if consumers of the
element mark it as not live.
2023-01-25 16:13:03 +00:00
Sanchayan Maity
92344bf8ac gst: Accept MP3 and FLAC for compressed sink 2023-01-24 08:44:14 +00:00
Robert Mader
6bf47e0bfa pipewiresrc: Always advertise support for DmaBuf
Quoting https://docs.pipewire.org/page_dma_buf.html section "v4l2":
```
It's the the responsibility of the producer while the add_buffer event
to choose DMA-BUF as the used buffer type even though no modifier is
present, if it can guarantee, that the used buffer is mmapable.
```

As Gstreamer internally can mmap dmabufs just fine, support this case.
This enables dmabuf support with V4L2 and libcamera.

This was also tested against Gnome-Shell, which correctly handles this
case and only chooses DmaBuf if the negotiated format has a modifier,
i.e. if the Gstreamer peer supports the format with
`GST_CAPS_FEATURE_MEMORY_DMABUF`.

Fixes 602aa7d541
2023-01-12 11:27:27 +00:00
Robert Mader
17c53577e8 gst: Log buffer memory type
This is helpful when one wants to ensure the right memory type is used,
independently from the negotiated format.
2023-01-12 11:27:27 +00:00
Wim Taymans
cab3e3c1ce clarify deprecated use of NODE_TARGET 2023-01-10 17:21:02 +01:00
Wim Taymans
c3032c70b6 keys: move NODE_TARGET to deprecated properties
Add PW_ENABLE_DEPRECATED to some places where we can not yet
avoid removing support.
2023-01-10 17:17:34 +01:00
Wim Taymans
a7df07c449 gst: don't set the deprecated path anymore
Just use the target_object property instead which uses the object.serial
is is less prone to races when the object id is recycled.
2023-01-10 16:47:47 +01:00
Robert Mader
602aa7d541 pipewiresrc: Reenable DMABuf support
This was disabled in 15b4c58e as under various circumstances Gstreamer
pipelines would mmap the DMABufs, which can be very slow in various cases.
One typical example of that is screen casting using a dedicated graphics card.

Thus we only want to use DMABufs if the peer element advertises support for
`GST_CAPS_FEATURE_MEMORY_DMABUF`, ensuring no mapping will happen if we
set the format accordingly.

This allows pipewiresrc to be used with DMABufs for fully accelerated
pipelines or in combination with a download element such as `gldownload`[1]
without regressing the commit above. The `gldownload` approach mirrors
what webrtc (Chromium/Firefox) does, but without duplicating the
functionality into pipewiresrc.

While on it, also implement dmabuf negotiation according to
https://docs.pipewire.org/page_dma_buf.html with the modifiers
`DRM_FORMAT_MOD_INVALID` and `DRM_FORMAT_MOD_LINEAR` in order to allow
dmabuf negotiation with more modern clients, including Gnome-Shell.

1: for now use something like `glupload ! glcolorconvert ! gldownload` -
   `gldownload` does not support importing DMABufs yet but `glupload` does.
2023-01-08 09:17:19 +00:00
Robert Mader
be2757c121 gstpipewireformat: Fully handle SPA_CHOICE_Step
The step value was not used.
2023-01-06 11:16:52 +00:00
Robert Mader
be99aa1eba gst: deviceprodiver: Add fd property / camera portal support
Add a `fd` property to `GstPipeWireDeviceProvider` so it can be used
with fds obtained from e.g. the camera xdg-desktop-portal.

This is needed so apps like Cheese or Camera can easily implement the
camera portal.
2022-12-27 23:43:22 +01:00
Robert Mader
2bc3e0ca10 gst: deviceprodiver: Use GstPipeWireCore and some cleanups
Quoting the commit introducing `GstPipeWireCore`:
```
Make all sources in the same process with the same fd share the
connection to the server. This makes it possible to set the same
fd on multiple sources/sinks and have them all use the same
connection, like when capturing multiple monitors from screencast
with the portal.
```

Do the same for `GstPipeWireDeviceProvider`, so it can share a
connection with device sinks as well. This will be needed for fd based
connections introduced in the next commit.

Further more it allows some cleanups.

1: 70652d1a37
2022-12-27 23:36:36 +01:00
Wim Taymans
638de5a3b7 gst: set stride to 0
We don't really know any better yet.
2022-12-08 13:39:58 +01:00
Robert Mader
2ed7afb76c gst: Implement SPA_META_VideoTransform support
Many Gstreamer elements support transforming buffers via the
`image-orientation` tag. Use it to implement support for the new
VideoTransform meta.

In order for Gstreamer pipelines to enable support for these tags
usually the rotate method has to be set to `auto` or `automatic`,
e.g. `videoflip method=automatic`, `glimagesink rotate-method=automatic`
or `waylandsink rotate-method=auto`.
2022-12-05 18:40:00 +01:00
Wim Taymans
e3ece6db54 gst: hide the libcamera device provider 2022-11-10 09:38:46 +01:00
James Hilliard
1ea1d525c1 gst: copy buffer memory in dequeue_buffer using gst_memory_copy
When always-copy is enabled we should copy buffer memory instead of
sharing buffer memory and using gst_buffer_copy_deep.

This should ensure we recycle the parent buffer as soon as the memory
is copied.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
2022-08-20 09:30:44 -06:00
James Hilliard
d61d787afa gst: log warnings if pw_stream_queue_buffer fails
There seem to be some latent issues with buffer recycling, add some
additional logging to simplify tracing buffer recycling issues.
2022-06-24 09:11:42 +00:00
Wim Taymans
5363bdcfcb gst: protect negotiated field with lock
Move the lock around the negotiated field.

See !1287
2022-06-21 13:19:32 +02:00
Wim Taymans
6c310cf5e2 gst: add client-properties
To update the client properties of the connection.

Fixes #1573
2022-06-03 13:00:52 +02:00
James Hilliard
64e8dee3a7 gst: dup buffer file descriptor before allocating
Since gst_fd_allocator_alloc lazy mmap's the buffer to the assigned
file descriptor we can get downstream mmap failures if the pipewire
src(such as the v4l2 spa plugin) closes the file descriptor before
it gets mmap'd. To prevent the closed original file descriptor from
causing a mmap failure dup the file descriptor so that the original
being closed doesn't invalidate the descriptor passed to
gst_fd_allocator_alloc.

Add some more validation to dequeue_buffer as well.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
2022-06-02 06:44:10 +00:00
James Hilliard
a1f33a99df gst: dequeue a shared buffer instead of original pool buffer
This seems to prevent the pool buffer from getting corrupted.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
2022-06-01 04:09:59 -06:00
James Hilliard
7305d38b85 gstpipewiresrc: don't mix tabs and spaces
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
2022-05-31 02:46:27 -06:00
James Hilliard
7cc509b117 buffers: ensure buffer size does not exceed maxsize
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
2022-05-31 07:25:31 +00:00
George Kiagiadakis
bf0ff347c1 pipewiresink: trigger process() manually when in driver mode
When in driver mode (mode=provide), the process() function is never
called. It needs to be triggered manually every now and then.

This fixes starting a mode=provide sink, but it doesn't fix re-starting
it... if the client disconnects while streaming, all buffers are getting
filled up and the pool blocks in aqcuiring one more; when the client
connects again, even if we signal the cond to unblock the pool, it still
can't acquire any more buffers and deadlocks.

Relates to: #1980
2022-05-31 07:24:41 +00:00