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.
This commit is contained in:
Sanchayan Maity 2025-03-19 19:54:46 +05:30 committed by Arun Raghavan
parent d37b0b4cd2
commit eb534b4515

View file

@ -1099,14 +1099,34 @@ handle_format_change (GstPipeWireSrc *pwsrc,
}
pw_peer_caps = gst_caps_from_format (param);
if (pw_peer_caps && pwsrc->possible_caps) {
GST_DEBUG_OBJECT (pwsrc, "peer caps %" GST_PTR_FORMAT, pw_peer_caps);
GST_DEBUG_OBJECT (pwsrc, "possible caps %" GST_PTR_FORMAT, pwsrc->possible_caps);
pwsrc->caps = gst_caps_intersect_full (pw_peer_caps,
pwsrc->possible_caps,
GST_CAPS_INTERSECT_FIRST);
/*
* We expect pw_peer_caps to be fixed caps as we receive that from
* PipeWire. See pw_context_find_format() and SPA_PARAM_Format.
* possible_caps can be non-fixated caps based on what is downstream
* in the pipeline.
*
* The intersection result above might give us non-fixated caps. A
* possible scenario for this is the below pipeline.
* pipewiresrc ! audioconvert ! audio/x-raw,rate=44100,channels=2 ! ..
*
* So we fixate the caps explicitly here.
*/
pwsrc->caps = gst_caps_fixate (pwsrc->caps);
gst_caps_maybe_fixate_dma_format (pwsrc->caps);
}
if (pwsrc->caps && gst_caps_is_fixed (pwsrc->caps)) {
if (pwsrc->caps) {
g_return_if_fail (gst_caps_is_fixed (pwsrc->caps));
pwsrc->negotiated = TRUE;
structure = gst_caps_get_structure (pwsrc->caps, 0);