Commit graph

420 commits

Author SHA1 Message Date
Philippe Normand
96ac4ae10d pipewiresrc: Fix caps leak
pwsrc->possible_caps wasn't un-reffed before re-assignment.
2025-09-15 18:01:53 +00:00
Robert Mader
5f3ae4376e gst: pool: Keep dmabufs mapped
Downstream elements accessing dmabufs from the CPU currently need to map
and unmap buffers on every frame.
While the kernel's page cache avoids most overhead, this still requires a
round-trip through the kernel and possibly non-negligible work in
`dma_buf_mmap()`. Keeping the buffers mapped avoids that without causing
additional syncronization work, as the later should only happen when
`DMA_BUF_IOCTL_SYNC` is triggered in `gst_dmabuf_mem_map()`.

A common scenario where this matters is clients using cameras. The
downstream elements in question may not be aware of dmabufs - e.g.
`videoconvert` - or fail to import the dmabuf and fall back to import
from memory - e.g. `glupload`.

Notes:
 - GstShmAllocator implicitly does this already.
 - We could also do this in the MemFd case, however I'm less convinced
   about the trade-offs.
2025-08-24 13:54:32 +02:00
Robert Mader
95497f8777 gst: pool: Remove last g_slice remnants
It has long been deprecated and just makes the code harder to read.
2025-08-24 13:48:33 +02:00
Robert Mader
e8ae244b2b gst: src: Promote 'set format' log to info
Follow various other elements like glupload and gtk4paintablesink and
print the negotiated caps at a higher priority than debug. A small
quality of life improvement to facilitate debugging.
2025-08-13 22:41:38 +02:00
Wim Taymans
e317edcfb9 pod: rework the parser
Make a new body.h file with some functions to deal with pod and their
body. Make the iter.h functions use mostly this.

Rework the parser so that it only uses body.h functions. With the separation
of pod+body, we can read and verify the pod once and then use the
verified copy to handle the rest of the body safely.

We do this because iter.h only works in pods in memory that doesn't change
because it is vulnerable to modifications of the data after verifying it.

The new parser is not vulnerable to this and will not cause invalid
memory access when used on shared memory. There is however no need for
atomic operations to read the headers, whever is read is either valid
and useable of invalid and rejected.

See #4822
2025-07-29 15:15:02 +02:00
Arun Raghavan
51d4d5ec3c gst: pipewiresrc: Expose cursor position as a ROI meta 2025-07-11 11:57:59 -04:00
Demi Marie Obenour
3c3ead2784 gst: whitespace fix
No functional change.
2025-07-10 14:05:23 +00:00
Robert Mader
9debb4b814 gst: pipewireformat: Validate fourcc before converting to string
gst_video_dma_drm_fourcc_to_string() asserts when called with
DRM_FORMAT_INVALID.
2025-07-08 11:38:28 +00:00
Albert Sjolund
2581575bd1 gst: fix leak in sink_update_params
buffer_pool_get_config returns a copy of the config structure, but it is
never freed in this function. Add a gst_structure_free to fix the leak
2025-07-08 13:07:44 +02:00
Michael Olbrich
a77c1cbd0b gst: pipewireformat: enforce DMA_DRM when possible
with memory:DMABuf, DMA_DRM should be used as 'format'. So only add
formats to 'format' if there is no equivalent drm format.
2025-06-27 12:57:40 +00:00
Michael Olbrich
7795e06563 gst: add colorimetry support 2025-06-27 12:57:01 +00:00
Elliot Chen
43441a4d69 pipewiresrc: fix sending last buffer failure if waiting operation exits in advance 2025-06-23 16:16:13 +00:00
Elliot Chen
72e0fe0479 pipewiresrc: add provide clock property 2025-06-13 08:10:20 +00:00
Jonas Holmberg
930f2f3e2d gst: deviceprovider: take a ref to devices
When _probe() is called, take a ref to the newly created devices instead
if sinking the floating ref, since gst_clear_object() is called when
core is disconnected. Otherwise the devices will be freed before the
caller gets them.

Fixes the following assert in the caller:

g_object_is_floating: assertion 'G_IS_OBJECT (object)' failed

Or sometimes a segfault with the backtrace:

0  g_type_check_instance_is_fundamentally_a (type_instance=type_instance@entry=0x116c1b0, fundamental_type=fundamental_type@entry=80) at /usr/src/debug/glib-2.0/2.84.0/gobject/gtype.c:3918
1  0xb6d40cc6 in g_object_is_floating (_object=0x116c1b0) at /usr/src/debug/glib-2.0/2.84.0/gobject/gobject.c:3843
2  0xb6bc4c74 in gst_device_provider_get_devices (provider=0x109ba00) at /usr/src/debug/gstreamer1.0/1.24.12/gst/gstdeviceprovider.c:426
2025-06-09 16:50:18 +02:00
Robert Mader
e81fb77322 gst: src: Change DEFAULT_MIN_BUFFERS back to 1
The change from 1 to 8 was done without justification in the commit
message and possibly for debug purposes. Unfortunately it breaks
negotiation with the libcamera virtual pipeline, which defaults to
4 buffers.

Set the the value to 1 again as successful negotiation - even with an
unusually low number of buffers - is usually more desirable than an
error.

Fixes: 98b7dc7c0 ("gst: don't do set_caps from the pipewire callback")
2025-05-25 04:03:06 +02:00
Taruntej Kanakamalla
882542e001 gst: sink: minor type fix 2025-05-12 21:31:30 +00:00
Taruntej Kanakamalla
608bf93f7a gst: sink: minor formatting fixes
follow up of !2337
2025-05-09 07:13:36 +00:00
Taruntej Kanakamalla
d5e2cc94cd gst: sink: update clock before every trigger process
Get the clock pointer using the io_changed stream event.
and update the clock before triggering the process

The clock needs to be updated in the data loop thread
and before triggering the process so move the calls to
`pw_stream_trigger_process` from gstreamer thread context
into the data loop thread context by invoking a callback
and update the clock inside the data loop callback
before the trigger
2025-05-08 18:57:44 +05:30
Arun Raghavan
21a468a9cd gst: Add H.265 support
Same as H.264 for now, we might eventually want to add more stream
formats etc.
2025-05-05 07:38:25 +00:00
Philippe Normand
2e409c0237 gst: src: Attach video meta when receiving DMABufs from PipeWire
Fixes getDisplayMedia() in WebKitGTK after regression introduced by:
https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/2330
2025-04-22 10:48:00 +01:00
Arun Raghavan
ebe9381236 gst: handle blocks and size allocation for encoded format
In case of encoded video we get n_planes as 0 from the video info so
passing that as n_datas is failing during the buffer negotiation. Make
sure to use an appropriate value based on whether we have raw video or
not.

Co-authored-by: Taruntej Kanakamalla <taruntej@asymptotic.io>
2025-04-17 15:21:38 -04:00
Sanchayan Maity
bb1bb07f6c gstpipewiresrc: Handle stream being disconnected
When PW source is used with something like Camera and the camera is
disconnected, all buffers are removed and stream will be paused.

When using PW sink with source, the sink side pipeline can go to EOS.
This again results in all the buffers being removed and stream being
paused on the source side. PW source side pipeline can also crash if
the sink was in the middle of frame copying a buffer to render which
got removed.

Handle this scenario by sending a flush-start event at the start of
buffer removal and flush-stop at the end followed by an end of stream
or pipeline error depending on user selection.
2025-04-09 07:45:27 +00:00
Sanchayan Maity
77143e54d9 gstpipewiresrc: Fix re-linking for audio
For a pipeline like below, we might want to dynamically switch the audio
source.

gst-launch-1.0 -e pipewiresrc autoconnect=false ! queue ! audioconvert ! autoaudiosink

On switching to a different audio source, any one of driver, quantum
or clock rate might change which changes the return `result` value of
gst_pipewire_clock_get_internal_time.

This can result in the basesrc create function incorrectly waiting in
gst_clock_id_wait. We post clock lost message to fix this. In the case
of gst-launch, it will set the pipeline to PAUSED and then PLAYING to
to force a new clock and a new base_time distribution.

Without the clock lost message, the following can be seen

before re-linking to a different source
0:00:30.887602864 79499 0x7fffe8000d40 DEBUG              GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:00:17.024565416 now 0:00:17.024109144 diff (time-now) 456272

after re-linking to a different source
0:00:45.790843245 79499 0x7fffe8000d40 DEBUG              GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:00:31.927694059 now 0:00:17.066883864 diff (time-now) 14860810195

With the clock lost message, the following can be seen

before re-linking to a different source
0:01:09.336533552 89461 0x7fffe8000d40 DEBUG              GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:00:58.198536772 now 0:00:58.197444926 diff (time-now) 1091846

after re-linking to a different source
0:01:21.659827958 89461 0x7fffe8000d40 DEBUG              GST_CLOCK gstsystemclock.c:1158:gst_system_clock_id_wait_jitter_unlocked:<pipewireclock0> entry 0x7fffd803fad0 time 0:28:24.853517646 now 0:28:24.853527204 diff (time-now) -9558

Note the difference in `time` and `now` fields of the above log message.

This is easy to reproduce by using a pipewiresink as the audio source
with a pipeline like below, as one of the sources during switching.

gst-launch-1.0 -e audiotestsrc wave=ticks ! audioconvert ! audio/x-raw,format=F32LE,rate=48000,channels=1 !
pipewiresink stream-properties="props,media.class=Audio/Source,node.description=pwsink" client-name=pwsink

Applications need to handle the GST_MESSAGE_CLOCK_LOST message in their
bus handlers.
2025-04-03 19:20:34 +05:30
Arun Raghavan
dd683176c2 gst: sink: Set provide clock flag if not in provide mode
Handle a theoretical corner case of an element that is first started
with mode=provide, and then restarted without mode=provide.
2025-04-03 06:59:31 -04:00
Wim Taymans
832c5a6d25 fix printf modifier for gsize
Fixes #4641
2025-04-02 13:25:31 +02:00
Taruntej Kanakamalla
ee2c6eb41e gst: sink: Manage buffer pool memory manually
Let's make sure we own the memory in buffers, so that we can be
resilient to the PW link going away. This currently maintains the status
quo of copying data into the pipewirepool for sending to the remote end,
but moves the allocation of buffers so that ownership is maintained by
the sink in all cases.

There are some tricky corners, especially with bufferpool vs. buffers
param negotiation -- bufferpool parameters can be negotiated in
GStreamer before the link even comes up, so we try to adapt the buffers
param to use the negotiated value. For now, that is more brittle than
tying those two aspects together. We can revisit this if we can find a
way to tie pipeline state and link state more closely.

Co-authored-by: Arun Raghavan <arun@asymptotic.io>
2025-04-02 08:20:38 +00:00
Arun Raghavan
1b258f4ecc gst: sink: Only add VideoCrop meta for video 2025-04-02 08:20:38 +00:00
Wim Taymans
5f4c0cdd1e improve debug and error reporting a little 2025-03-28 16:08:57 +01:00
Wim Taymans
afb4a2f49c Revert "gst: src: Minor fix for offsets"
This reverts commit 4c200183b9.

The offset is already applied when we share/copy the memory in the
target buffer.
2025-03-26 17:56:14 +01:00
Arun Raghavan
d7cb68bfc7 gst: pool: Some refinements to min/max handling
A number of changes for correctness.

  1) We expose the actualy min and max values we support in the
     allocation query.

  2) We don't support max_buffers as 0, as unlimited buffers is not an
     option

  3) In ParamBuffers, we request the max_buffers from bufferpool config,
     as we cannot dynamically allocate buffers
2025-03-26 12:08:35 -04:00
Arun Raghavan
5ef13489db gst: sink: Correctly set size and offset on planar data
We need to make sure the memory sizes are correctly initialised so the
meta makes sense, and we don't copy the meta from the input buffer as
that doesn't make sense given we have our own meta already.
2025-03-26 12:08:35 -04:00
Arun Raghavan
dfdc3e333a gst: sink: Minor style consistency fixup 2025-03-26 09:51:53 -04:00
Arun Raghavan
4c200183b9 gst: src: Minor fix for offsets
I don't see any actual usage of left/top padding (yet), but we should
account for chunk offset in addition to the overall size.
2025-03-26 09:26:38 -04:00
Wim Taymans
cc6081b70d gst: fix video metadata offsets
The offsets in GStreamer are always offsets into the buffer memory where
the plane starts so set this to the accumulated plane sizes.
2025-03-26 12:30:41 +01:00
Wim Taymans
5fb9716ce7 gst: require a buffer size of at least 1
Setting the default size to 0 and outside of the min/max range now means
that there is no suggestion for the size and it should use the
suggestion of the peer.
2025-03-26 09:52:22 +01:00
Arun Raghavan
439d5d04fe gst: sink: Don't provide clock in provide mode
Counter-intuitive as it seems, when we are driving the clock, we can't
also provide a clock from PipeWire to the pipeline -- we need the
pipeline to drive the graph.

So we make the mode control whether we provide a clock or not.
2025-03-25 21:38:15 +00:00
Sanchayan Maity
3c62d29a55 gstpipewiresrc: Fix re-linking
When using PW source, one might want to dynamically link PW source to
a different source. Setting possible_caps to NULL prevents the caps
intersect from returning a successful result on format change. Do not
set possible_caps to NULL as we get that from peer caps which should
stay the same ideally for the duration of pipeline run. That allows
re-linking PW source any number of times with a pipeline like below.

gst-launch-1.0 pipewiresrc autoconnect=false ! queue ! video/x-raw,format=YUY2 ! videoconvert ! xvimagesink

The above pipeline can be made to switch between a camera source and a
screen capture source like wf-recorder.

Note that this fix only improves the status quo and won't work if the
peer caps change due to a re-negotiation.
2025-03-25 17:49:13 +00:00
Sanchayan Maity
eb534b4515 gst: pipewiresrc: Fixate caps if intersect did not return fixated caps
We might end up in a situation where depending on the pipeline,
intersect might not give us fixated caps.

Possible example of such a pipeline can be below.

gst-launch-1.0 -e pipewiresrc target-object=<path> ! audioconvert !
audio/x-raw,format=S16LE,rate=48000,channels=2 ! lamemp3enc !
filesink location=test.mp3

This results in non-fixated caps like below when intersecting caps from
format param and possible_caps which depends on what we have downstream
in the pipeline.

audio/x-raw, layout=(string)interleaved, format=(string)S16LE, rate=(int)48000, channels=(int)2, channel-mask=(bitmask)0x0000000000000003;
audio/x-raw, layout=(string)interleaved, format=(string)S16LE, rate=(int)48000, channels=(int)2

To fix this, fixate the caps explicitly.
2025-03-25 15:47:28 +00:00
Philippe Normand
d37b0b4cd2 gst: deviceprovider: Fix a leak and a heap-use-after-free
The device passed to gst_device_provider_device_add() is transfer:floating, so
we need increase its ref, otherwise the pointer we keep internally will be a
dangling ref.

Also gst_device_provider_device_remove() doesn't actually release the device, so
we have to do it ourselves.

Fixes #4616
2025-03-25 15:33:43 +00:00
Philippe Normand
e584cee066 gst: src: Fix buffer pool handling in case of caps renegotiation
In case negotiation is first attempted with unfixed caps, bufferpool support was
unconditionally disabled. Then at a second caps negotiation attempt it wasn't
restored according to the property value.
2025-03-25 12:50:42 +00:00
Sanchayan Maity
b8d5334462 gst: pipewireformat: Do not use RANGE if values are equal
This fixes assertion from the underlying gst_value_collect_int_range
when using gst_caps_set_simple with range types when the values are
equal.
2025-03-21 16:18:28 +05:30
Sanchayan Maity
d329dac6ba gst: Do not use video only info for SPA_PARAM_BUFFERS_blocks
We mistakenly used video only info for setting SPA_PARAM_BUFFERS_blocks,
which would be completely incorrect for audio.

Fixes 6c9ada270.
2025-03-14 12:41:38 +00:00
Sanchayan Maity
6c9ada270b gst: Fix handling of video planar formats
Tiled formats are not tested and supported yet.
2025-03-13 18:53:23 +05:30
Taruntej Kanakamalla
a4a9d3540d gst: sink: copy frames if video buffer from other pool
In case of the video, if the buffer to be rendered is from upstream and
not from the pipewirepool, map the memory into video frames and copy the
frames instead of doing a buffer copy.

Avoid splitting of buffers in the case of video, because that might break
the frame layout, especially planar formats, for the applications which
use pipewiresink as a camera source to capture video.
2025-03-04 22:54:47 +05:30
Philippe Normand
9296d1645f gst: deviceprovider: Notify default devices changes
This allows GStreamer apps using GstDeviceMonitor to be notified when the user
changes the default input/output devices.
2025-02-25 12:48:21 +00:00
Taruntej Kanakamalla
333b5aaa36 gst: don't use bufferpool for audio by default
Deprecate the `always-copy` property in pipewiresrc and use the new
property `use-bufferpool` in both pipewiresrc and pipewiresink to
specify whether to use the gstpipewirepool or not.

The gstpipewirepool is used for video by default unless `use-bufferpool`
is set to `false` and it is not used for audio by default unless
`use-bufferpool` is set to `true`
2025-02-03 17:22:34 +00:00
Olle Axelsson
1cc00923db gst: Ensure possible_caps exists before comparing caps
During negotiation, ensure that possible_caps exists before calling
gst_caps_intersect_full(). Sometimes possible_caps seem to be NULL which
cause the GST_IS_CAPS assert to fail.

The reason for the occasional NULL possible_caps during initial
negotiation is unknown, but this is also possible during renegotiation.
The handle_format_change() may be triggered before the next create(),
win which case we have not yet discovered in the streaming thread that
we are in the NOT_NEGOTIATED state. We should guard against this
possibility as well.
2025-01-30 13:38:55 -05:00
Taruntej Kanakamalla
180967bb64 gst: pipewirepool:fix lock evasion in release_buffer 2025-01-24 10:51:29 +00:00
Arun Raghavan
800cd53c56 gst: sink: Whitespace fixups 2025-01-23 10:17:19 -05:00
Arun Raghavan
9ece286c90 gst: Fix up some debug logs
Copy-pasto in the pause code, plus let's use GST_DEBUG_OBJECT() so
we can track which pool is affected.
2025-01-23 10:17:19 -05:00