コード例 #1
0
static GstElement *
default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
{
  GstElement *pipeline;

  pipeline = gst_pipeline_new ("media-pipeline");
  gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));

  return pipeline;
}
コード例 #2
0
static GstElement *
create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
{
  GstElement *pipeline;

  pipeline = gst_pipeline_new ("media-pipeline");
  if (global_clock == NULL) {
    g_print ("No clock!!!!\n");
  } else {
    gst_pipeline_use_clock (GST_PIPELINE (pipeline), global_clock);
  }
  gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));

  return pipeline;
}
コード例 #3
0
static GstElement *
default_create_pipeline (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
{
  GstElement *pipeline;

  pipeline = gst_pipeline_new ("media-pipeline");

  /* FIXME 2.0: This should be done by the caller, not the vfunc. Every
   * implementation of the vfunc has to call it otherwise at the end.
   * Also it does not allow use to add further behaviour here that could
   * be reused by subclasses that chain up */
  gst_rtsp_media_take_pipeline (media, GST_PIPELINE_CAST (pipeline));

  return pipeline;
}
コード例 #4
0
static int act_gstreamer_render (VisPluginData *plugin, VisVideo *video, VisAudio *audio)
{
	GstreamerPrivate *priv = visual_object_get_private (VISUAL_OBJECT (plugin));
	static int playing = 0;

	if (playing == 0) {
		char pipe[1024];

		gst_init (NULL, NULL);
/*
		snprintf(pipe, 1024, "filesrc location=%s ! decodebin ! ffmpegcolorspace ! "
				"videoscale ! video/x-raw-rgb,bpp=32,depth=32,width=%d,height=%d,"
				"red_mask=0xff000000,green_mask=0x00ff0000,blue_mask=0x0000ff00 !"
				"fakesink name=sink sync=true", "test.mpg", video->width, video->height);

*/
		snprintf(pipe, 1024, "filesrc location=%s ! decodebin ! ffmpegcolorspace ! "
				"video/x-raw-rgb,bpp=24,depth=24 ! "
				"fakesink name=sink signal-handoffs=true", "test.mpg");

		GError *err = NULL;

		priv->pipe = GST_PIPELINE_CAST(gst_parse_launch (pipe, &err));

		if (err) {
			visual_log (VISUAL_LOG_ERROR, "Failed to create pipeline", err->message);
			return;
		}

		gst_element_set_state (GST_ELEMENT (priv->pipe), GST_STATE_PLAYING);

		g_signal_connect (gst_bin_get_by_name_recurse_up (GST_BIN (priv->pipe), "sink"),
				"handoff", G_CALLBACK (have_data), video);

		playing = 1;
	}

//	g_signal_handlers_disconnect_by_func (gst_bin_get_by_name_recurse_up (GST_BIN (priv->pipe), "sink"),
//			G_CALLBACK (have_data), priv->old_video);


	gst_bin_iterate (GST_BIN (priv->pipe));

	priv->old_video = video;

	return 0;
}
コード例 #5
0
/* takes a snapshot of the running_time of the pipeline and store this as the
 * element start_time. This is the time we will set as the running_time of the
 * pipeline when we go to PLAYING next. */
static void
pipeline_update_start_time (GstElement * element)
{
  GstPipeline *pipeline = GST_PIPELINE_CAST (element);
  GstClock *clock;

  GST_OBJECT_LOCK (element);
  if ((clock = element->clock)) {
    GstClockTime now;

    gst_object_ref (clock);
    GST_OBJECT_UNLOCK (element);

    /* calculate the time when we stopped */
    now = gst_clock_get_time (clock);
    gst_object_unref (clock);

    GST_OBJECT_LOCK (element);
    /* store the current running time */
    if (GST_ELEMENT_START_TIME (pipeline) != GST_CLOCK_TIME_NONE) {
      if (now != GST_CLOCK_TIME_NONE)
        GST_ELEMENT_START_TIME (pipeline) = now - element->base_time;
      else
        GST_WARNING_OBJECT (element,
            "Clock %s returned invalid time, can't calculate "
            "running_time when going to the PAUSED state",
            GST_OBJECT_NAME (clock));

      /* we went to PAUSED, when going to PLAYING select clock and new
       * base_time */
      pipeline->priv->update_clock = TRUE;
    }
    GST_DEBUG_OBJECT (element,
        "start_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT
        ", base_time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (GST_ELEMENT_START_TIME (pipeline)),
        GST_TIME_ARGS (now), GST_TIME_ARGS (element->base_time));
  }
  GST_OBJECT_UNLOCK (element);
}
コード例 #6
0
/**
 * gst_validate_monitor_factory_create:
 * @target: The #GstObject to create a #GstValidateMonitor for
 * @runner: The #GstValidateRunner to use for the new monitor
 * @parent: (nullable): The parent of the new monitor
 *
 * Create a new monitor for @target and starts monitoring it.
 *
 * Returns: (transfer full): The newly created #GstValidateMonitor
 */
GstValidateMonitor *
gst_validate_monitor_factory_create (GstObject * target,
    GstValidateRunner * runner, GstValidateMonitor * parent)
{
  GstValidateMonitor *monitor = NULL;
  g_return_val_if_fail (target != NULL, NULL);

  monitor = g_object_get_data ((GObject *) target, "validate-monitor");
  if (monitor) {
    GST_INFO_OBJECT (target, "Is already monitored by %" GST_PTR_FORMAT,
        monitor);

    return g_object_ref (monitor);
  }

  if (GST_IS_PAD (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_pad_monitor_new (GST_PAD_CAST
            (target), runner, GST_VALIDATE_ELEMENT_MONITOR_CAST (parent)));
  } else if (GST_IS_PIPELINE (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_pipeline_monitor_new
        (GST_PIPELINE_CAST (target), runner, parent));
  } else if (GST_IS_BIN (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_bin_monitor_new (GST_BIN_CAST
            (target), runner, parent));
  } else if (GST_IS_ELEMENT (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_element_monitor_new
        (GST_ELEMENT_CAST (target), runner, parent));
  } else {
    g_assert_not_reached ();
  }

  return monitor;
}
コード例 #7
0
/* intercept the bus messages from our children. We watch for the ASYNC_START
 * message with is posted by the elements (sinks) that require a reset of the
 * running_time after a flush. ASYNC_START also brings the pipeline back into
 * the PAUSED, pending PAUSED state. When the ASYNC_DONE message is received the
 * pipeline will redistribute the new base_time and will bring the elements back
 * to the desired state of the pipeline. */
static void
gst_pipeline_handle_message (GstBin * bin, GstMessage * message)
{
  GstPipeline *pipeline = GST_PIPELINE_CAST (bin);

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_RESET_TIME:
    {
      GstClockTime running_time;

      gst_message_parse_reset_time (message, &running_time);

      /* reset our running time if we need to distribute a new base_time to the
       * children. */
      reset_start_time (pipeline, running_time);
      break;
    }
    case GST_MESSAGE_CLOCK_LOST:
    {
      GstClock *clock;

      gst_message_parse_clock_lost (message, &clock);

      GST_OBJECT_LOCK (bin);
      if (clock == GST_ELEMENT_CAST (bin)->clock) {
        GST_DEBUG_OBJECT (bin, "Used clock '%s' got lost",
            GST_OBJECT_NAME (clock));
        pipeline->priv->update_clock = TRUE;
      }
      GST_OBJECT_UNLOCK (bin);
    }
    default:
      break;
  }
  GST_BIN_CLASS (parent_class)->handle_message (bin, message);
}
コード例 #8
0
/* MT safe */
static GstStateChangeReturn
gst_pipeline_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
  GstPipeline *pipeline = GST_PIPELINE_CAST (element);
  GstClock *clock;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      GST_OBJECT_LOCK (element);
      if (element->bus)
        gst_bus_set_flushing (element->bus, FALSE);
      GST_OBJECT_UNLOCK (element);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_OBJECT_LOCK (element);
      pipeline->priv->update_clock = TRUE;
      GST_OBJECT_UNLOCK (element);

      /* READY to PAUSED starts running_time from 0 */
      reset_start_time (pipeline, 0);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
    {
      GstClockTime now, start_time, last_start_time, delay;
      gboolean update_clock;
      GstClock *cur_clock;

      GST_DEBUG_OBJECT (element, "selecting clock and base_time");

      GST_OBJECT_LOCK (element);
      cur_clock = element->clock;
      if (cur_clock)
        gst_object_ref (cur_clock);
      /* get the desired running_time of the first buffer aka the start_time */
      start_time = GST_ELEMENT_START_TIME (pipeline);
      last_start_time = pipeline->priv->last_start_time;
      pipeline->priv->last_start_time = start_time;
      /* see if we need to update the clock */
      update_clock = pipeline->priv->update_clock;
      pipeline->priv->update_clock = FALSE;
      delay = pipeline->delay;
      GST_OBJECT_UNLOCK (element);

      /* running time changed, either with a PAUSED or a flush, we need to check
       * if there is a new clock & update the base time */
      /* only do this for top-level, however */
      if (GST_OBJECT_PARENT (element) == NULL &&
          (update_clock || last_start_time != start_time)) {
        GST_DEBUG_OBJECT (pipeline, "Need to update start_time");

        /* when going to PLAYING, select a clock when needed. If we just got
         * flushed, we don't reselect the clock. */
        if (update_clock) {
          GST_DEBUG_OBJECT (pipeline, "Need to update clock.");
          clock = gst_element_provide_clock (element);
        } else {
          GST_DEBUG_OBJECT (pipeline,
              "Don't need to update clock, using old clock.");
          /* only try to ref if cur_clock is not NULL */
          if (cur_clock)
            gst_object_ref (cur_clock);
          clock = cur_clock;
        }

        if (clock) {
          now = gst_clock_get_time (clock);
        } else {
          GST_DEBUG_OBJECT (pipeline, "no clock, using base time of NONE");
          now = GST_CLOCK_TIME_NONE;
        }

        if (clock != cur_clock) {
          /* now distribute the clock (which could be NULL). If some
           * element refuses the clock, this will return FALSE and
           * we effectively fail the state change. */
          if (!gst_element_set_clock (element, clock))
            goto invalid_clock;

          /* if we selected and distributed a new clock, let the app
           * know about it */
          gst_element_post_message (element,
              gst_message_new_new_clock (GST_OBJECT_CAST (element), clock));
        }

        if (clock)
          gst_object_unref (clock);

        if (start_time != GST_CLOCK_TIME_NONE && now != GST_CLOCK_TIME_NONE) {
          GstClockTime new_base_time = now - start_time + delay;
          GST_DEBUG_OBJECT (element,
              "start_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT
              ", base_time %" GST_TIME_FORMAT,
              GST_TIME_ARGS (start_time), GST_TIME_ARGS (now),
              GST_TIME_ARGS (new_base_time));

          gst_element_set_base_time (element, new_base_time);
        } else {
          GST_DEBUG_OBJECT (pipeline,
              "NOT adjusting base_time because start_time is NONE");
        }
      } else {
        GST_DEBUG_OBJECT (pipeline,
            "NOT adjusting base_time because we selected one before");
      }

      if (cur_clock)
        gst_object_unref (cur_clock);
      break;
    }
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
    {
      /* we take a start_time snapshot before calling the children state changes
       * so that they know about when the pipeline PAUSED. */
      pipeline_update_start_time (element);
      break;
    }
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      reset_start_time (pipeline, 0);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
  }

  result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
    {
      /* Take a new snapshot of the start_time after calling the state change on
       * all children. This will be the running_time of the pipeline when we go
       * back to PLAYING */
      pipeline_update_start_time (element);
      break;
    }
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
    {
      GstBus *bus;
      gboolean auto_flush;

      /* grab some stuff before we release the lock to flush out the bus */
      GST_OBJECT_LOCK (element);
      if ((bus = element->bus))
        gst_object_ref (bus);
      auto_flush = pipeline->priv->auto_flush_bus;
      GST_OBJECT_UNLOCK (element);

      if (bus) {
        if (auto_flush) {
          gst_bus_set_flushing (bus, TRUE);
        } else {
          GST_INFO_OBJECT (element, "not flushing bus, auto-flushing disabled");
        }
        gst_object_unref (bus);
      }
      break;
    }
  }
  return result;

  /* ERRORS */
invalid_clock:
  {
    /* we generate this error when the selected clock was not
     * accepted by some element */
    GST_ELEMENT_ERROR (pipeline, CORE, CLOCK,
        (_("Selected clock cannot be used in pipeline.")),
        ("Pipeline cannot operate with selected clock"));
    GST_DEBUG_OBJECT (pipeline,
        "Pipeline cannot operate with selected clock %p", clock);
    if (clock)
      gst_object_unref (clock);
    return GST_STATE_CHANGE_FAILURE;
  }
}