mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	gst-source: fix state changes
Only go to READY in setup_pipeline, this is enough to get the caps. We don't want to go to PAUSED yet because we don't want to negotiate a format. Mark the source busy after we configured the capsfilter so that we can let the source negotiate correctly.
This commit is contained in:
		
							parent
							
								
									b86eb22922
								
							
						
					
					
						commit
						5c7447fb4d
					
				
					 3 changed files with 57 additions and 47 deletions
				
			
		| 
						 | 
					@ -416,8 +416,6 @@ gst_pinos_socket_sink_open (GstPinosSocketSink * this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GError *error = NULL;
 | 
					  GError *error = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  this->cache = gst_burst_cache_new (sizeof (MyReader));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  this->context = g_main_context_new ();
 | 
					  this->context = g_main_context_new ();
 | 
				
			||||||
  this->loop = g_main_loop_new (this->context, TRUE);
 | 
					  this->loop = g_main_loop_new (this->context, TRUE);
 | 
				
			||||||
  GST_DEBUG ("context %p, loop %p", this->context, this->loop);
 | 
					  GST_DEBUG ("context %p, loop %p", this->context, this->loop);
 | 
				
			||||||
| 
						 | 
					@ -453,7 +451,6 @@ gst_pinos_socket_sink_close (GstPinosSocketSink * this)
 | 
				
			||||||
  g_clear_pointer (&this->loop, g_main_loop_unref);
 | 
					  g_clear_pointer (&this->loop, g_main_loop_unref);
 | 
				
			||||||
  g_clear_pointer (&this->context, g_main_context_unref);
 | 
					  g_clear_pointer (&this->context, g_main_context_unref);
 | 
				
			||||||
  g_hash_table_remove_all (this->hash);
 | 
					  g_hash_table_remove_all (this->hash);
 | 
				
			||||||
  g_clear_pointer (&this->cache, g_object_unref);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -799,6 +796,7 @@ gst_pinos_socket_sink_finalize (GObject * object)
 | 
				
			||||||
  GstPinosSocketSink *this = GST_PINOS_SOCKET_SINK (object);
 | 
					  GstPinosSocketSink *this = GST_PINOS_SOCKET_SINK (object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_clear_pointer (&this->hash, g_hash_table_unref);
 | 
					  g_clear_pointer (&this->hash, g_hash_table_unref);
 | 
				
			||||||
 | 
					  g_clear_pointer (&this->cache, g_object_unref);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  G_OBJECT_CLASS (parent_class)->finalize (object);
 | 
					  G_OBJECT_CLASS (parent_class)->finalize (object);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -879,6 +877,7 @@ static void
 | 
				
			||||||
gst_pinos_socket_sink_init (GstPinosSocketSink * this)
 | 
					gst_pinos_socket_sink_init (GstPinosSocketSink * this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  this->hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
					  this->hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 | 
				
			||||||
 | 
					  this->cache = gst_burst_cache_new (sizeof (MyReader));
 | 
				
			||||||
  this->allocator = gst_tmpfile_allocator_new ();
 | 
					  this->allocator = gst_tmpfile_allocator_new ();
 | 
				
			||||||
  this->fdmanager = pinos_fd_manager_get (PINOS_FD_MANAGER_DEFAULT);
 | 
					  this->fdmanager = pinos_fd_manager_get (PINOS_FD_MANAGER_DEFAULT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -379,7 +379,7 @@ on_new_buffer (GObject    *gobject,
 | 
				
			||||||
        if (buf == NULL)
 | 
					        if (buf == NULL)
 | 
				
			||||||
          buf = gst_buffer_new ();
 | 
					          buf = gst_buffer_new ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        GST_INFO ("pts %" G_GUINT64_FORMAT ", dts_offset %"G_GUINT64_FORMAT "\n", hdr.pts, hdr.dts_offset);
 | 
					        GST_INFO ("pts %" G_GUINT64_FORMAT ", dts_offset %"G_GUINT64_FORMAT, hdr.pts, hdr.dts_offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (GST_CLOCK_TIME_IS_VALID (hdr.pts)) {
 | 
					        if (GST_CLOCK_TIME_IS_VALID (hdr.pts)) {
 | 
				
			||||||
          GST_BUFFER_PTS (buf) = hdr.pts;
 | 
					          GST_BUFFER_PTS (buf) = hdr.pts;
 | 
				
			||||||
| 
						 | 
					@ -495,6 +495,16 @@ parse_stream_properties (GstPinosSrc *pinossrc, PinosProperties *props)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  const gchar *var;
 | 
					  const gchar *var;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var = pinos_properties_get (props, "pinos.latency.is-live");
 | 
				
			||||||
 | 
					  pinossrc->is_live = var ? (atoi (var) == 1) : FALSE;
 | 
				
			||||||
 | 
					  gst_base_src_set_live (GST_BASE_SRC (pinossrc), pinossrc->is_live);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var = pinos_properties_get (props, "pinos.latency.min");
 | 
				
			||||||
 | 
					  pinossrc->min_latency = var ? (GstClockTime) atoi (var) : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var = pinos_properties_get (props, "pinos.latency.max");
 | 
				
			||||||
 | 
					  pinossrc->max_latency = var ? (GstClockTime) atoi (var) : GST_CLOCK_TIME_NONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var = pinos_properties_get (props, "pinos.clock.type");
 | 
					  var = pinos_properties_get (props, "pinos.clock.type");
 | 
				
			||||||
  if (var != NULL) {
 | 
					  if (var != NULL) {
 | 
				
			||||||
    GST_DEBUG_OBJECT (pinossrc, "got clock type %s", var);
 | 
					    GST_DEBUG_OBJECT (pinossrc, "got clock type %s", var);
 | 
				
			||||||
| 
						 | 
					@ -517,15 +527,6 @@ parse_stream_properties (GstPinosSrc *pinossrc, PinosProperties *props)
 | 
				
			||||||
            pinossrc->clock, TRUE));
 | 
					            pinossrc->clock, TRUE));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  var = pinos_properties_get (props, "pinos.latency.is-live");
 | 
					 | 
				
			||||||
  pinossrc->is_live = var ? (atoi (var) == 1) : FALSE;
 | 
					 | 
				
			||||||
  gst_base_src_set_live (GST_BASE_SRC (pinossrc), pinossrc->is_live);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  var = pinos_properties_get (props, "pinos.latency.max");
 | 
					 | 
				
			||||||
  pinossrc->max_latency = var ? (GstClockTime) atoi (var) : GST_CLOCK_TIME_NONE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  var = pinos_properties_get (props, "pinos.latency.min");
 | 
					 | 
				
			||||||
  pinossrc->min_latency = var ? (GstClockTime) atoi (var) : 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -829,7 +830,7 @@ static GstFlowReturn
 | 
				
			||||||
gst_pinos_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
 | 
					gst_pinos_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GstPinosSrc *pinossrc;
 | 
					  GstPinosSrc *pinossrc;
 | 
				
			||||||
  GstClockTime base_time;
 | 
					  GstClockTime pts, dts, base_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinossrc = GST_PINOS_SRC (psrc);
 | 
					  pinossrc = GST_PINOS_SRC (psrc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -856,20 +857,25 @@ gst_pinos_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pinos_main_loop_wait (pinossrc->loop);
 | 
					    pinos_main_loop_wait (pinossrc->loop);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  base_time = GST_ELEMENT_CAST (psrc)->base_time;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (GST_BUFFER_PTS_IS_VALID (*buffer) && GST_BUFFER_PTS (*buffer) >= base_time)
 | 
					 | 
				
			||||||
    GST_BUFFER_PTS (*buffer) -= base_time;
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    GST_BUFFER_PTS (*buffer) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (GST_BUFFER_DTS_IS_VALID (*buffer) && GST_BUFFER_DTS (*buffer) >= base_time)
 | 
					 | 
				
			||||||
    GST_BUFFER_DTS (*buffer) -= base_time;
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    GST_BUFFER_DTS (*buffer) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pinos_main_loop_unlock (pinossrc->loop);
 | 
					  pinos_main_loop_unlock (pinossrc->loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  base_time = GST_ELEMENT_CAST (psrc)->base_time;
 | 
				
			||||||
 | 
					  pts = GST_BUFFER_PTS (*buffer);
 | 
				
			||||||
 | 
					  dts = GST_BUFFER_DTS (*buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (GST_CLOCK_TIME_IS_VALID (pts))
 | 
				
			||||||
 | 
					    pts = (pts >= base_time ? pts - base_time : 0);
 | 
				
			||||||
 | 
					  if (GST_CLOCK_TIME_IS_VALID (dts))
 | 
				
			||||||
 | 
					    dts = (dts >= base_time ? dts - base_time : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GST_INFO ("pts %" G_GUINT64_FORMAT ", dts %"G_GUINT64_FORMAT
 | 
				
			||||||
 | 
					      ", base-time %"GST_TIME_FORMAT" -> %"GST_TIME_FORMAT", %"GST_TIME_FORMAT,
 | 
				
			||||||
 | 
					      GST_BUFFER_PTS (*buffer), GST_BUFFER_DTS (*buffer), GST_TIME_ARGS (base_time),
 | 
				
			||||||
 | 
					      GST_TIME_ARGS (pts), GST_TIME_ARGS (dts));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GST_BUFFER_PTS (*buffer) = pts;
 | 
				
			||||||
 | 
					  GST_BUFFER_DTS (*buffer) = dts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return GST_FLOW_OK;
 | 
					  return GST_FLOW_OK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
not_negotiated:
 | 
					not_negotiated:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,6 +111,8 @@ bus_handler (GstBus     *bus,
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
setup_pipeline (PinosGstSource *source, GError **error)
 | 
					setup_pipeline (PinosGstSource *source, GError **error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -118,6 +120,7 @@ setup_pipeline (PinosGstSource *source, GError **error)
 | 
				
			||||||
  GstBus *bus;
 | 
					  GstBus *bus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  priv->pipeline = gst_pipeline_new (NULL);
 | 
					  priv->pipeline = gst_pipeline_new (NULL);
 | 
				
			||||||
 | 
					  gst_pipeline_set_latency (GST_PIPELINE_CAST (priv->pipeline), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_debug ("gst-source %p: setup pipeline", source);
 | 
					  g_debug ("gst-source %p: setup pipeline", source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -153,13 +156,9 @@ start_pipeline (PinosGstSource *source, GError **error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_debug ("gst-source %p: starting pipeline", source);
 | 
					  g_debug ("gst-source %p: starting pipeline", source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ret = gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
 | 
					  ret = gst_element_set_state (priv->pipeline, GST_STATE_READY);
 | 
				
			||||||
  if (ret == GST_STATE_CHANGE_FAILURE)
 | 
					  if (ret == GST_STATE_CHANGE_FAILURE)
 | 
				
			||||||
    goto paused_failed;
 | 
					    goto ready_failed;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ret = gst_element_get_state (priv->pipeline, NULL, NULL, -1);
 | 
					 | 
				
			||||||
  if (ret == GST_STATE_CHANGE_FAILURE)
 | 
					 | 
				
			||||||
    goto paused_failed;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  query = gst_query_new_caps (NULL);
 | 
					  query = gst_query_new_caps (NULL);
 | 
				
			||||||
  gst_element_query (priv->element, query);
 | 
					  gst_element_query (priv->element, query);
 | 
				
			||||||
| 
						 | 
					@ -170,9 +169,9 @@ start_pipeline (PinosGstSource *source, GError **error)
 | 
				
			||||||
  return TRUE;
 | 
					  return TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* ERRORS */
 | 
					  /* ERRORS */
 | 
				
			||||||
paused_failed:
 | 
					ready_failed:
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    GST_ERROR_OBJECT (source, "failed state change");
 | 
					    GST_ERROR_OBJECT (source, "failed state change to READY");
 | 
				
			||||||
    gst_element_set_state (priv->pipeline, GST_STATE_NULL);
 | 
					    gst_element_set_state (priv->pipeline, GST_STATE_NULL);
 | 
				
			||||||
    if (error)
 | 
					    if (error)
 | 
				
			||||||
      *error = g_error_new (G_IO_ERROR,
 | 
					      *error = g_error_new (G_IO_ERROR,
 | 
				
			||||||
| 
						 | 
					@ -231,7 +230,11 @@ set_state (PinosSource      *source,
 | 
				
			||||||
      gchar *address;
 | 
					      gchar *address;
 | 
				
			||||||
      gint port;
 | 
					      gint port;
 | 
				
			||||||
      GstClockTime base_time;
 | 
					      GstClockTime base_time;
 | 
				
			||||||
 | 
					      gboolean live;
 | 
				
			||||||
 | 
					      GstClockTime min_latency, max_latency;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
 | 
				
			||||||
 | 
					      gst_element_get_state (priv->pipeline, NULL, NULL, -1);
 | 
				
			||||||
      gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
 | 
					      gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
 | 
				
			||||||
      gst_element_get_state (priv->pipeline, NULL, NULL, -1);
 | 
					      gst_element_get_state (priv->pipeline, NULL, NULL, -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,21 +258,22 @@ set_state (PinosSource      *source,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      query = gst_query_new_latency ();
 | 
					      query = gst_query_new_latency ();
 | 
				
			||||||
      if (gst_element_query (GST_ELEMENT_CAST (priv->pipeline), query)) {
 | 
					      if (gst_element_query (GST_ELEMENT_CAST (priv->pipeline), query)) {
 | 
				
			||||||
        gboolean live;
 | 
					 | 
				
			||||||
        GstClockTime min_latency, max_latency;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        gst_query_parse_latency (query, &live, &min_latency, &max_latency);
 | 
					        gst_query_parse_latency (query, &live, &min_latency, &max_latency);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
        GST_DEBUG_OBJECT (priv->pipeline,
 | 
					        live = FALSE;
 | 
				
			||||||
            "got min latency %" GST_TIME_FORMAT ", max latency %"
 | 
					        min_latency = 0;
 | 
				
			||||||
            GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
 | 
					        max_latency = -1;
 | 
				
			||||||
            GST_TIME_ARGS (max_latency), live);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        pinos_properties_setf (priv->props, "pinos.latency.is-live", "%d", live);
 | 
					 | 
				
			||||||
        pinos_properties_setf (priv->props, "pinos.latency.min", "%"G_GUINT64_FORMAT, min_latency);
 | 
					 | 
				
			||||||
        pinos_properties_setf (priv->props, "pinos.latency.max", "%"G_GUINT64_FORMAT, max_latency);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      gst_query_unref (query);
 | 
					      gst_query_unref (query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      GST_DEBUG_OBJECT (priv->pipeline,
 | 
				
			||||||
 | 
					          "got min latency %" GST_TIME_FORMAT ", max latency %"
 | 
				
			||||||
 | 
					          GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
 | 
				
			||||||
 | 
					          GST_TIME_ARGS (max_latency), live);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      pinos_properties_setf (priv->props, "pinos.latency.is-live", "%d", live);
 | 
				
			||||||
 | 
					      pinos_properties_setf (priv->props, "pinos.latency.min", "%"G_GUINT64_FORMAT, min_latency);
 | 
				
			||||||
 | 
					      pinos_properties_setf (priv->props, "pinos.latency.max", "%"G_GUINT64_FORMAT, max_latency);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case PINOS_SOURCE_STATE_ERROR:
 | 
					    case PINOS_SOURCE_STATE_ERROR:
 | 
				
			||||||
| 
						 | 
					@ -355,6 +359,7 @@ on_socket_notify (GObject    *gobject,
 | 
				
			||||||
  PinosProperties *props;
 | 
					  PinosProperties *props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_object_get (gobject, "socket", &socket, NULL);
 | 
					  g_object_get (gobject, "socket", &socket, NULL);
 | 
				
			||||||
 | 
					  GST_DEBUG ("got socket %p", socket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (socket == NULL) {
 | 
					  if (socket == NULL) {
 | 
				
			||||||
    GSocket *prev_socket = g_object_steal_data (gobject, "last-socket");
 | 
					    GSocket *prev_socket = g_object_steal_data (gobject, "last-socket");
 | 
				
			||||||
| 
						 | 
					@ -363,7 +368,6 @@ on_socket_notify (GObject    *gobject,
 | 
				
			||||||
      g_object_unref (prev_socket);
 | 
					      g_object_unref (prev_socket);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    pinos_source_report_busy (PINOS_SOURCE (source));
 | 
					 | 
				
			||||||
    g_signal_emit_by_name (priv->sink, "add", socket);
 | 
					    g_signal_emit_by_name (priv->sink, "add", socket);
 | 
				
			||||||
    g_object_set_data_full (gobject, "last-socket", socket, g_object_unref);
 | 
					    g_object_set_data_full (gobject, "last-socket", socket, g_object_unref);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -400,6 +404,7 @@ on_socket_notify (GObject    *gobject,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* this is what we use as the final format for the output */
 | 
					    /* this is what we use as the final format for the output */
 | 
				
			||||||
    g_object_set (gobject, "format", format, NULL);
 | 
					    g_object_set (gobject, "format", format, NULL);
 | 
				
			||||||
 | 
					    pinos_source_report_busy (PINOS_SOURCE (source));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (format) {
 | 
					  if (format) {
 | 
				
			||||||
    pinos_source_update_possible_formats (PINOS_SOURCE (source), format);
 | 
					    pinos_source_update_possible_formats (PINOS_SOURCE (source), format);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue