mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05: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",
 | 
					  GST_DEBUG_OBJECT (basesrc, "connect capture with path %s, target-object %s",
 | 
				
			||||||
                    pwsrc->path, pwsrc->target_object);
 | 
					                    pwsrc->path, pwsrc->target_object);
 | 
				
			||||||
  pwsrc->negotiated = FALSE;
 | 
					
 | 
				
			||||||
  enum pw_stream_flags flags;
 | 
					  enum pw_stream_flags flags;
 | 
				
			||||||
  flags = PW_STREAM_FLAG_DONT_RECONNECT |
 | 
					  flags = PW_STREAM_FLAG_DONT_RECONNECT |
 | 
				
			||||||
	  PW_STREAM_FLAG_ASYNC;
 | 
						  PW_STREAM_FLAG_ASYNC;
 | 
				
			||||||
| 
						 | 
					@ -953,6 +953,9 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
 | 
				
			||||||
  pw_thread_loop_get_time (pwsrc->core->loop, &abstime,
 | 
					  pw_thread_loop_get_time (pwsrc->core->loop, &abstime,
 | 
				
			||||||
                  GST_PIPEWIRE_DEFAULT_TIMEOUT * SPA_NSEC_PER_SEC);
 | 
					                  GST_PIPEWIRE_DEFAULT_TIMEOUT * SPA_NSEC_PER_SEC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pwsrc->possible_caps = possible_caps;
 | 
				
			||||||
 | 
					  pwsrc->negotiated = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while (TRUE) {
 | 
					  while (TRUE) {
 | 
				
			||||||
    enum pw_stream_state state = pw_stream_get_state (pwsrc->stream, &error);
 | 
					    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);
 | 
					  negotiated_caps = g_steal_pointer (&pwsrc->caps);
 | 
				
			||||||
 | 
					  pwsrc->possible_caps = NULL;
 | 
				
			||||||
  pw_thread_loop_unlock (pwsrc->core->loop);
 | 
					  pw_thread_loop_unlock (pwsrc->core->loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (negotiated_caps == NULL)
 | 
					  if (negotiated_caps == NULL)
 | 
				
			||||||
| 
						 | 
					@ -1015,6 +1019,8 @@ no_common_caps:
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
connect_error:
 | 
					connect_error:
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
					    g_clear_pointer (&pwsrc->caps, gst_caps_unref);
 | 
				
			||||||
 | 
					    pwsrc->possible_caps = NULL;
 | 
				
			||||||
    GST_DEBUG_OBJECT (basesrc, "connect error");
 | 
					    GST_DEBUG_OBJECT (basesrc, "connect error");
 | 
				
			||||||
    pw_thread_loop_unlock (pwsrc->core->loop);
 | 
					    pw_thread_loop_unlock (pwsrc->core->loop);
 | 
				
			||||||
    return FALSE;
 | 
					    return FALSE;
 | 
				
			||||||
| 
						 | 
					@ -1025,16 +1031,23 @@ static void
 | 
				
			||||||
handle_format_change (GstPipeWireSrc *pwsrc,
 | 
					handle_format_change (GstPipeWireSrc *pwsrc,
 | 
				
			||||||
                   const struct spa_pod *param)
 | 
					                   const struct spa_pod *param)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (pwsrc->caps)
 | 
					  g_autoptr (GstCaps) pw_peer_caps = NULL;
 | 
				
			||||||
          gst_caps_unref(pwsrc->caps);
 | 
					
 | 
				
			||||||
 | 
					  g_clear_pointer (&pwsrc->caps, gst_caps_unref);
 | 
				
			||||||
  if (param == NULL) {
 | 
					  if (param == NULL) {
 | 
				
			||||||
    GST_DEBUG_OBJECT (pwsrc, "clear format");
 | 
					    GST_DEBUG_OBJECT (pwsrc, "clear format");
 | 
				
			||||||
    pwsrc->caps = NULL;
 | 
					 | 
				
			||||||
    pwsrc->negotiated = FALSE;
 | 
					    pwsrc->negotiated = FALSE;
 | 
				
			||||||
    pwsrc->is_video = FALSE;
 | 
					    pwsrc->is_video = FALSE;
 | 
				
			||||||
    return;
 | 
					    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)) {
 | 
					  if (pwsrc->caps && gst_caps_is_fixed (pwsrc->caps)) {
 | 
				
			||||||
    pwsrc->negotiated = TRUE;
 | 
					    pwsrc->negotiated = TRUE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,7 @@ struct _GstPipeWireSrc {
 | 
				
			||||||
  gboolean autoconnect;
 | 
					  gboolean autoconnect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GstCaps *caps;
 | 
					  GstCaps *caps;
 | 
				
			||||||
 | 
					  GstCaps *possible_caps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gboolean is_video;
 | 
					  gboolean is_video;
 | 
				
			||||||
  GstVideoInfo video_info;
 | 
					  GstVideoInfo video_info;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue