mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
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.
This commit is contained in:
parent
05b1c9d0c8
commit
e6f2aa6ce0
2 changed files with 19 additions and 5 deletions
|
|
@ -937,7 +937,7 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
|
|||
|
||||
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s, target-object %s",
|
||||
pwsrc->path, pwsrc->target_object);
|
||||
pwsrc->negotiated = FALSE;
|
||||
|
||||
enum pw_stream_flags flags;
|
||||
flags = PW_STREAM_FLAG_DONT_RECONNECT |
|
||||
PW_STREAM_FLAG_ASYNC;
|
||||
|
|
@ -953,6 +953,9 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
|
|||
pw_thread_loop_get_time (pwsrc->core->loop, &abstime,
|
||||
GST_PIPEWIRE_DEFAULT_TIMEOUT * SPA_NSEC_PER_SEC);
|
||||
|
||||
pwsrc->possible_caps = possible_caps;
|
||||
pwsrc->negotiated = FALSE;
|
||||
|
||||
while (TRUE) {
|
||||
enum pw_stream_state state = pw_stream_get_state (pwsrc->stream, &error);
|
||||
|
||||
|
|
@ -972,6 +975,7 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
|
|||
}
|
||||
|
||||
negotiated_caps = g_steal_pointer (&pwsrc->caps);
|
||||
pwsrc->possible_caps = NULL;
|
||||
pw_thread_loop_unlock (pwsrc->core->loop);
|
||||
|
||||
if (negotiated_caps == NULL)
|
||||
|
|
@ -1015,6 +1019,8 @@ no_common_caps:
|
|||
}
|
||||
connect_error:
|
||||
{
|
||||
g_clear_pointer (&pwsrc->caps, gst_caps_unref);
|
||||
pwsrc->possible_caps = NULL;
|
||||
GST_DEBUG_OBJECT (basesrc, "connect error");
|
||||
pw_thread_loop_unlock (pwsrc->core->loop);
|
||||
return FALSE;
|
||||
|
|
@ -1025,16 +1031,23 @@ static void
|
|||
handle_format_change (GstPipeWireSrc *pwsrc,
|
||||
const struct spa_pod *param)
|
||||
{
|
||||
if (pwsrc->caps)
|
||||
gst_caps_unref(pwsrc->caps);
|
||||
g_autoptr (GstCaps) pw_peer_caps = NULL;
|
||||
|
||||
g_clear_pointer (&pwsrc->caps, gst_caps_unref);
|
||||
if (param == NULL) {
|
||||
GST_DEBUG_OBJECT (pwsrc, "clear format");
|
||||
pwsrc->caps = NULL;
|
||||
pwsrc->negotiated = FALSE;
|
||||
pwsrc->is_video = FALSE;
|
||||
return;
|
||||
}
|
||||
pwsrc->caps = gst_caps_from_format (param);
|
||||
|
||||
pw_peer_caps = gst_caps_from_format (param);
|
||||
if (pw_peer_caps) {
|
||||
pwsrc->caps = gst_caps_intersect_full (pw_peer_caps,
|
||||
pwsrc->possible_caps,
|
||||
GST_CAPS_INTERSECT_FIRST);
|
||||
gst_caps_maybe_fixate_dma_format (pwsrc->caps);
|
||||
}
|
||||
|
||||
if (pwsrc->caps && gst_caps_is_fixed (pwsrc->caps)) {
|
||||
pwsrc->negotiated = TRUE;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct _GstPipeWireSrc {
|
|||
gboolean autoconnect;
|
||||
|
||||
GstCaps *caps;
|
||||
GstCaps *possible_caps;
|
||||
|
||||
gboolean is_video;
|
||||
GstVideoInfo video_info;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue