A bug was introduced with the refactoring in da26563. In arm_init,
the buffer passed to spa_cpu_read_file is allocated and it is just
going to return that. So cpuinfo will actually point to buffer on
the stack, which need not be freed with a call to free.
The crash resulting with the incorrect free.
root@dragonboard-845c:~# pipewire --version
munmap_chunk(): invalid pointer
[ 185.037284] audit: type=1701 audit(1659949975.843:14): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=2243 comm="pipewire" exe="/usr/bin/pipewire" sig=6 res=1
Aborted
root@dragonboard-845c:~# wireplumber --version
munmap_chunk(): invalid pointer
[ 193.453693] audit: type=1701 audit(1659949984.255:15): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=2244 comm="wireplumber" exe="/usr/bin/wireplumber" sig=6 res=1
Aborted
Backtrace from the crash
(gdb) bt
!0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
!1 0x0000fffff7d8edd8 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
!2 0x0000fffff7d4a390 in __GI_raise (sig=sig@entry=6) at /usr/src/debug/glibc/2.36-r0/sysdeps/posix/raise.c:26
!3 0x0000fffff7d37498 in __GI_abort () at abort.c:79
!4 0x0000fffff7d83374 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0xfffff7e5fc20 "%s\n") at /usr/src/debug/glibc/2.36-r0/sysdeps/posix/libc_fatal.c:155
!5 0x0000fffff7d988c0 in malloc_printerr (str=str@entry=0xfffff7e5a7f0 "munmap_chunk(): invalid pointer") at malloc.c:5660
!6 0x0000fffff7d98aac in munmap_chunk (p=p@entry=0xffffffffd258) at malloc.c:3054
!7 0x0000fffff7d9d068 in __GI___libc_free (mem=mem@entry=0xffffffffd268) at malloc.c:3375
!8 0x0000fffff7cd36cc in arm_init (impl=impl@entry=0xaaaaaaac8c48) at /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu-arm.c:97
!9 0x0000fffff7cd391c in impl_init (factory=<optimized out>, handle=0xaaaaaaac8c48, info=0xffffffffe548, support=<optimized out>, n_support=<optimized out>) at /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu.c:264
!10 0x0000fffff7f3a234 in load_spa_handle (lib=<optimized out>, factory_name=factory_name@entry=0xfffff7f6d768 "support.cpu", info=info@entry=0xffffffffe548, n_support=1,
support=support@entry=0xfffff7fb0488 <global_support+88>) at /usr/src/debug/pipewire/1.0-r0/src/pipewire/pipewire.c:280
!11 0x0000fffff7f3a5b0 in add_interface (factory_name=factory_name@entry=0xfffff7f6d768 "support.cpu", type=type@entry=0xfffff7f62310 "Spa:Pointer:Interface:CPU", info=info@entry=0xffffffffe548,
support=0xfffff7fb0430 <global_support>) at /usr/src/debug/pipewire/1.0-r0/src/pipewire/pipewire.c:358
!12 0x0000fffff7f3b3f8 in pw_init (argc=argc@entry=0xffffffffea5c, argv=argv@entry=0xffffffffea50) at /usr/src/debug/pipewire/1.0-r0/src/pipewire/pipewire.c:661
!13 0x0000aaaaaaaa1104 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/pipewire/1.0-r0/src/daemon/pipewire.c:79
(gdb) f 8
!8 0x0000fffff7cd36cc in arm_init (impl=impl@entry=0xaaaaaaac8c48) at /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu-arm.c:97
97 /usr/src/debug/pipewire/1.0-r0/spa/plugins/support/cpu-arm.c: No such file or directory.
(gdb) info locals
flags = 122
cpuinfo = 0xffffffffd268 "processor\t: 0\nBogoMIPS\t: 38.40\nFeatures\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop\nCPU implementer\t: 0x51\nCPU architecture: 8\nCPU variant\t.
line = 0xaaaaaaac8ce0 "\310\252\252\252\n"
buffer = "processor\t: 0\nBogoMIPS\t: 38.40\nFeatures\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop\nCPU implementer\t: 0x51\nCPU architecture: 8\nCPU variant\t: 0x7\nCPU pa"...
arch = <optimized out>
__func__ = "arm_init"
Split files into separate files.
Move type annotations to a matching -types.h files.
Move helpers to matching -utils.h files.
Add helpers to parse generic audio and video info.
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
The drm format modifier value `0` is actually `DRM_FORMAT_MOD_LINEAR`,
a commonly used modifier. Unfortunately there appears to be no value
that can savely used as placeholder for "no value", as e.g.
`DRM_FORMAT_MOD_INVALID` is often used to indicate an implicit modifier.
Thus add a new flag that clearly indicates whether the modifier
value is set or not, add it to `spa_video_info_raw` and the util
functions.
Closes https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2943
According to https://docs.pipewire.org/page_dma_buf.html, i.e. announce
each format once with, once without `SPA_FORMAT_VIDEO_modifier`
property.
Note: currently libcamera always uses `DRM_FORMAT_MOD_LINEAR` (`== 0`),
so `pix.modifier()` returning `0` does not mean that no modifier is
supported.
This is needed for clients using the new DMABuf negotiation pattern,
such as gstpipewiresrc after 602aa7d5.
The drm format modifier value `0` is actually `DRM_FORMAT_MOD_LINEAR`,
a commonly used modifier. Unfortunately there appears to be no value
that can savely used as placeholder for "no value", as e.g.
`DRM_FORMAT_MOD_INVALID` is often used to indicate an implicit modifier.
Thus add an extra field that clearly indicates whether the modifier
value is set or not, add it to the util fuctions and use it for the
current only user, the libcamera backend.
Fixes 5a6da7d5e1
Closes https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2943
PIPEWIRE_NODE is mapped to TARGET_OBJECT so it contains the serial or
the node name.
Make sure pw-stream maps this to TARGET_OBJECT.
Make JACK use the PIPEWIRE_NODE for serial or node.name.
The pulse API uses either the node.name or object.serials so pass this
along in the TARGET_OBJECT instead of the NODE_TARGET now that
wireplumber handles this.
When we start the drain, we unpause the stream. When we conplete the
drain, we unpause again, which does nothing when the stream was already
unpaused. However, this leaves the drained state on the stream and so
the stream will never be able to play new data.
Trigger a new pw_stream_set_active() with the current stream state to
clear the drained state.
Fixes#2928
Copy the global quantum and rate limits before applying node specific
settings. Otherwise one node settings will propagate to the defaults
of the next nodes, which can result in impossible or wrong settings.
See #2925
Add a reconfigure state on the node that is set when the node was IDLE
or RUNNING when reconfigured.
The node state will be set to the running state as long as the
reconfigure state is active. When the node is running, the reconfigure
state is unset again and the node is allowed to IDLE as usual.
This fixes the case where an IDLE (but not paused node) will be
suspended when a rate change happens but will then not resume
afterwards.
This causes problems with rate changes and nodes that have the suspend
disabled by the session manager. They will be suspened anyway and this
can cause problems for devices that need to keep running to keep the
amplifiers active.
Fixes#2929
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.
Dictionaries are by default printed in their insertion order.
This is unergonimic when comparing properties created by different
clients, as they may insert them in different orders.