Beispiel #1
0
static void
_teardown_test (void)
{
  GstBus *bus;
  gst_element_set_state (demux, GST_STATE_NULL);

  bus = GST_ELEMENT_BUS (demux);
  gst_bus_set_flushing (bus, TRUE);
  gst_object_unref (bus);

  gst_pad_set_active (mjpg_pad, FALSE);
  gst_object_unref (mjpg_pad);
  if (h264_pad) {
    gst_pad_set_active (h264_pad, FALSE);
    gst_object_unref (h264_pad);
  }
  if (yuy2_pad) {
    gst_pad_set_active (yuy2_pad, FALSE);
    gst_object_unref (yuy2_pad);
  }
  if (nv12_pad) {
    gst_pad_set_active (nv12_pad, FALSE);
    gst_object_unref (nv12_pad);
  }
  if (jpg_pad) {
    gst_pad_set_active (jpg_pad, FALSE);
    gst_object_unref (jpg_pad);
  }
  if (gerror) {
    g_error_free (gerror);
    gerror = NULL;
  }
  if (error_debug) {
    g_free (error_debug);
    error_debug = NULL;
  }

  gst_object_unref (demux);
  mjpg_pad = h264_pad = yuy2_pad = nv12_pad = jpg_pad = NULL;
  demux = NULL;

  gst_caps_replace (&negotiated_caps_h264, NULL);
  gst_caps_replace (&negotiated_caps_yuy2, NULL);
  gst_caps_replace (&negotiated_caps_nv12, NULL);
  gst_caps_replace (&negotiated_caps_jpg, NULL);
}
static void
gst_device_monitor_init (GstDeviceMonitor * self)
{
    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                 GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorPrivate);

    self->priv->show_all = DEFAULT_SHOW_ALL;

    self->priv->bus = gst_bus_new ();
    gst_bus_set_flushing (self->priv->bus, TRUE);

    self->priv->providers = g_ptr_array_new ();
    self->priv->filters = g_ptr_array_new_with_free_func (
                              (GDestroyNotify) device_filter_free);

    self->priv->last_id = 1;
}
static void
bus_message_cb (GstBus * bus, GstMessage * message, GMainLoop * mainloop)
{
    switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR:
        g_print ("ERROR\n");
        gst_bus_set_flushing (bus, TRUE);
        g_main_loop_quit (mainloop);
        break;
    case GST_MESSAGE_EOS:
        g_print ("Done\n");
        g_main_loop_quit (mainloop);
        break;
    default:
        break;
    }
}
static void
cleanup_wavpackenc (GstElement * wavpackenc)
{
  GST_DEBUG ("cleanup_wavpackenc");

  gst_bus_set_flushing (bus, TRUE);
  gst_element_set_bus (wavpackenc, NULL);
  gst_object_unref (GST_OBJECT (bus));

  gst_element_set_state (wavpackenc, GST_STATE_NULL);

  gst_pad_set_active (mysrcpad, FALSE);
  gst_pad_set_active (mysinkpad, FALSE);
  gst_check_teardown_src_pad (wavpackenc);
  gst_check_teardown_sink_pad (wavpackenc);
  gst_check_teardown_element (wavpackenc);
}
/**
 * gst_discoverer_stop:
 * @discoverer: A #GstDiscoverer
 *
 * Stop the discovery of any pending URIs and clears the list of
 * pending URIS (if any).
 *
 * Since: 0.10.31
 */
void
gst_discoverer_stop (GstDiscoverer * discoverer)
{
  GST_DEBUG_OBJECT (discoverer, "Stopping...");

  if (!discoverer->priv->async) {
    GST_DEBUG_OBJECT (discoverer,
        "We were already stopped, or running synchronously");
    return;
  }

  DISCO_LOCK (discoverer);
  if (discoverer->priv->processing) {
    /* We prevent any further processing by setting the bus to
     * flushing and setting the pipeline to READY.
     * _reset() will take care of the rest of the cleanup */
    if (discoverer->priv->bus)
      gst_bus_set_flushing (discoverer->priv->bus, TRUE);
    if (discoverer->priv->pipeline)
      gst_element_set_state ((GstElement *) discoverer->priv->pipeline,
          GST_STATE_READY);
  }
  discoverer->priv->running = FALSE;
  DISCO_UNLOCK (discoverer);

  /* Remove timeout handler */
  if (discoverer->priv->timeoutid) {
    g_source_remove (discoverer->priv->timeoutid);
    discoverer->priv->timeoutid = 0;
  }
  /* Remove signal watch */
  if (discoverer->priv->sourceid) {
    g_source_remove (discoverer->priv->sourceid);
    discoverer->priv->sourceid = 0;
  }
  /* Unref main context */
  if (discoverer->priv->ctx) {
    g_main_context_unref (discoverer->priv->ctx);
    discoverer->priv->ctx = NULL;
  }
  discoverer_reset (discoverer);

  discoverer->priv->async = FALSE;

  GST_DEBUG_OBJECT (discoverer, "Stopped");
}
static gboolean
message_handler (GstBus * bus, GstMessage * message, gpointer user_data)
{
  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ELEMENT:{
      const GstStructure *s = gst_message_get_structure (message);
      const gchar *name = gst_structure_get_name (s);

      if (strcmp (name, "not-mounted") == 0) {
        GMountOperation *mop = gtk_mount_operation_new (NULL);
        GFile *file =
            G_FILE (g_value_get_object (gst_structure_get_value (s, "file")));

        g_print ("not-mounted\n");
        gst_element_set_state (pipeline, GST_STATE_NULL);
        gst_bus_set_flushing (bus, TRUE);

        g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE,
            mop, NULL, mount_cb, bus);

        g_object_unref (mop);
      }
      break;
    }

    case GST_MESSAGE_EOS:
      g_print ("EOS\n");
      gtk_main_quit ();
      break;
    case GST_MESSAGE_ERROR:{
      GError *err = NULL;

      gst_message_parse_error (message, &err, NULL);
      g_print ("error: %s\n", err->message);
      g_clear_error (&err);

      gtk_main_quit ();
      break;
    }
    default:
      break;
  }

  return TRUE;
}
Beispiel #7
0
static void
cleanup_element (GstElement * element)
{
  GstBus *bus;

  /* Free parsed buffers */
  gst_check_drop_buffers ();

  bus = GST_ELEMENT_BUS (element);
  gst_bus_set_flushing (bus, TRUE);
  gst_object_unref (bus);

  gst_pad_set_active (srcpad, FALSE);
  gst_pad_set_active (sinkpad, FALSE);
  gst_check_teardown_src_pad (element);
  gst_check_teardown_sink_pad (element);
  gst_check_teardown_element (element);
}
static void
mount_cb (GObject * obj, GAsyncResult * res, gpointer user_data)
{
  gboolean ret;
  GError *err = NULL;

  ret = g_file_mount_enclosing_volume_finish (G_FILE (obj), res, &err);

  if (ret) {
    g_print ("mounted successfully\n");
    gst_bus_set_flushing ((GstBus *) user_data, FALSE);

    gst_element_set_state (pipeline, GST_STATE_PLAYING);
  } else {
    g_print ("mounting failed: %s\n", err->message);
    g_clear_error (&err);
    gtk_main_quit ();
  }
}
Beispiel #9
0
static void
teardown_cmmlenc (void)
{
  /* free encoded buffers */
  g_list_foreach (buffers, buffer_unref, NULL);
  g_list_free (buffers);
  buffers = NULL;
  current_buf = NULL;

  gst_bus_set_flushing (bus, TRUE);
  gst_object_unref (bus);

  GST_DEBUG ("teardown_cmmlenc");
  gst_pad_set_active (srcpad, FALSE);
  gst_pad_set_active (sinkpad, FALSE);
  gst_check_teardown_src_pad (cmmlenc);
  gst_check_teardown_sink_pad (cmmlenc);
  gst_check_teardown_element (cmmlenc);
}
/**
 * gst_device_monitor_stop:
 * @monitor: A #GstDeviceProvider
 *
 * Stops monitoring the devices.
 *
 * Since: 1.4
 */
void
gst_device_monitor_stop (GstDeviceMonitor * monitor)
{
  guint i;

  g_return_if_fail (GST_IS_DEVICE_MONITOR (monitor));

  gst_bus_set_flushing (monitor->priv->bus, TRUE);

  GST_OBJECT_LOCK (monitor);
  for (i = 0; i < monitor->priv->providers->len; i++) {
    GstDeviceProvider *provider =
        g_ptr_array_index (monitor->priv->providers, i);

    if (gst_device_provider_can_monitor (provider))
      gst_device_provider_stop (provider);
  }
  monitor->priv->started = FALSE;
  GST_OBJECT_UNLOCK (monitor);

}
static void
cleanup_amrnbenc (GstElement * amrnbenc)
{
  GstBus *bus;

  /* free encoded buffers */
  g_list_foreach (buffers, buffer_unref, NULL);
  g_list_free (buffers);
  buffers = NULL;

  bus = GST_ELEMENT_BUS (amrnbenc);
  gst_bus_set_flushing (bus, TRUE);
  gst_object_unref (bus);

  GST_DEBUG ("cleanup_amrnbenc");
  gst_pad_set_active (srcpad, FALSE);
  gst_pad_set_active (sinkpad, FALSE);
  gst_check_teardown_src_pad (amrnbenc);
  gst_check_teardown_sink_pad (amrnbenc);
  gst_check_teardown_element (amrnbenc);
}
Beispiel #12
0
int gstreamer_stop(void)
{
	if (!gst_provider.play)
		return 0;

	dprintf("%s: in\n", __func__);

	GstBus *bus = gst_element_get_bus (gst_provider.play);
	gst_bus_set_flushing (bus, TRUE);

	GstState cur_state;
	gst_element_get_state (gst_provider.play, &cur_state, NULL, 0);
	if (cur_state > GST_STATE_READY) {
		dprintf ("%s: stopping %s\n", __func__, gst_provider.uri);
		gst_element_set_state (gst_provider.play, GST_STATE_READY);
	}
	gst_object_unref (bus);
	dprintf("%s: out\n", __func__);

	return 0;
}
/* Must be called with mutex locked. */
static void
gst_uri_downloader_stop (GstUriDownloader * downloader)
{
  GstPad *pad;
  GstElement *urisrc;

  if (!downloader->priv->urisrc)
    return;

  GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
      GST_ELEMENT_NAME (downloader->priv->urisrc));

  /* remove the bus' sync handler */
  gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL);
  /* unlink the source element from the internal pad */
  pad = gst_pad_get_peer (downloader->priv->pad);
  if (pad) {
    gst_pad_unlink (pad, downloader->priv->pad);
    gst_object_unref (pad);
  }
  urisrc = downloader->priv->urisrc;
  downloader->priv->urisrc = NULL;

  /* unlock so it doesn't block on chain function while changing state */
  g_mutex_unlock (&downloader->priv->lock);

  GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
      GST_ELEMENT_NAME (urisrc));

  /* set the element state to NULL */
  gst_element_set_state (urisrc, GST_STATE_NULL);
  gst_element_get_state (urisrc, NULL, NULL, GST_CLOCK_TIME_NONE);
  gst_element_set_bus (urisrc, NULL);
  gst_object_unref (urisrc);

  /* caller expects the mutex to be locked */
  g_mutex_lock (&downloader->priv->lock);
  gst_bus_set_flushing (downloader->priv->bus, TRUE);
}
Beispiel #14
0
static void
gst_pipeline_init (GstPipeline * pipeline)
{
  GstBus *bus;

  pipeline->priv = GST_PIPELINE_GET_PRIVATE (pipeline);

  /* set default property values */
  pipeline->priv->auto_flush_bus = DEFAULT_AUTO_FLUSH_BUS;
  pipeline->delay = DEFAULT_DELAY;

  /* create and set a default bus */
  bus = gst_bus_new ();
#if 0
  /* FIXME, disabled for 0.10.5 release as it caused to many regressions */
  /* Start our bus in flushing if appropriate */
  if (pipeline->priv->auto_flush_bus)
    gst_bus_set_flushing (bus, TRUE);
#endif

  gst_element_set_bus (GST_ELEMENT_CAST (pipeline), bus);
  GST_DEBUG_OBJECT (pipeline, "set bus %" GST_PTR_FORMAT " on pipeline", bus);
  gst_object_unref (bus);
}
static void
helper (gboolean flush)
{
    GstElement *filter;
    GstBus *bus;
    GstPad *mysrcpad;
    GstPad *mysinkpad;

    /* init */
    filter = gst_check_setup_element ("omx_dummy");
    mysrcpad = gst_check_setup_src_pad (filter, &srctemplate, NULL);
    mysinkpad = gst_check_setup_sink_pad (filter, &sinktemplate, NULL);

    gst_pad_set_active (mysrcpad, TRUE);
    gst_pad_set_active (mysinkpad, TRUE);

    /* need to know when we are eos */
    gst_pad_set_event_function (mysinkpad, test_sink_event);

    /* and notify the test run */
    eos_mutex = g_mutex_new ();
    eos_cond = g_cond_new ();
    eos_arrived = FALSE;

    g_object_set (G_OBJECT (filter), "library-name", "libomxil-foo.so", NULL);

    /* start */

    fail_unless_equals_int (gst_element_set_state (filter, GST_STATE_PLAYING),
                            GST_STATE_CHANGE_SUCCESS);

    bus = gst_bus_new ();

    gst_element_set_bus (filter, bus);

    /* send buffers in order*/
    {
        guint i;
        for (i = 0; i < BUFFER_COUNT; i++)
        {
            GstBuffer *inbuffer;
            inbuffer = gst_buffer_new_and_alloc (BUFFER_SIZE);
            GST_BUFFER_DATA(inbuffer)[0] = i;
            ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);

            fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);

            if (flush && i % FLUSH_AT == 0)
            {
                gst_pad_push_event (mysrcpad, gst_event_new_flush_start ());
                gst_pad_push_event (mysrcpad, gst_event_new_flush_stop ());
                i += FLUSH_AT;
            }
        }
    }

    {
        GstMessage *message;
        fail_if ((message = gst_bus_pop (bus)) != NULL);

        /* make sure there's no error on the bus */
        message = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
        fail_if (message);
    }

    gst_pad_push_event (mysrcpad, gst_event_new_eos ());
    /* need to wait a bit to make sure src pad task digested all and sent eos */
    g_mutex_lock (eos_mutex);
    while (!eos_arrived)
        g_cond_wait (eos_cond, eos_mutex);
    g_mutex_unlock (eos_mutex);

    /* check the order of the buffers*/
    if (!flush)
    {
        GList *cur;
        guint i;
        for (cur = buffers, i = 0; cur; cur = g_list_next (cur), i++)
        {
            GstBuffer *buffer;
            buffer = cur->data;
            fail_unless (GST_BUFFER_DATA(buffer)[0] == i);
        }
        fail_unless (i == BUFFER_COUNT);
    }

    /* cleanup */
    gst_bus_set_flushing (bus, TRUE);
    gst_element_set_bus (filter, NULL);
    gst_object_unref (GST_OBJECT (bus));
    gst_check_drop_buffers ();

    /* deinit */
    gst_element_set_state (filter, GST_STATE_NULL);

    gst_pad_set_active (mysrcpad, FALSE);
    gst_pad_set_active (mysinkpad, FALSE);
    gst_check_teardown_src_pad (filter);
    gst_check_teardown_sink_pad (filter);
    gst_check_teardown_element (filter);

    g_mutex_free (eos_mutex);
    g_cond_free (eos_cond);
}
/* 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;
  }
}
/**
 * gst_uri_downloader_fetch_uri_with_range:
 * @downloader: the #GstUriDownloader
 * @uri: the uri
 * @range_start: the starting byte index
 * @range_end: the final byte index, use -1 for unspecified
 *
 * Returns the downloaded #GstFragment
 */
GstFragment *
gst_uri_downloader_fetch_uri_with_range (GstUriDownloader *
    downloader, const gchar * uri, const gchar * referer, gboolean compress,
    gboolean refresh, gboolean allow_cache,
    gint64 range_start, gint64 range_end, GError ** err)
{
  GstStateChangeReturn ret;
  GstFragment *download = NULL;

  GST_DEBUG_OBJECT (downloader, "Fetching URI %s", uri);

  g_mutex_lock (&downloader->priv->download_lock);
  downloader->priv->err = NULL;
  downloader->priv->got_buffer = FALSE;

  GST_OBJECT_LOCK (downloader);
  if (downloader->priv->cancelled) {
    GST_DEBUG_OBJECT (downloader, "Cancelled, aborting fetch");
    goto quit;
  }

  if (!gst_uri_downloader_set_uri (downloader, uri, referer, compress, refresh,
          allow_cache)) {
    GST_WARNING_OBJECT (downloader, "Failed to set URI");
    goto quit;
  }

  gst_bus_set_flushing (downloader->priv->bus, FALSE);
  if (downloader->priv->download)
    g_object_unref (downloader->priv->download);
  downloader->priv->download = gst_fragment_new ();
  downloader->priv->download->range_start = range_start;
  downloader->priv->download->range_end = range_end;
  GST_OBJECT_UNLOCK (downloader);
  ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_READY);
  GST_OBJECT_LOCK (downloader);
  if (ret == GST_STATE_CHANGE_FAILURE || downloader->priv->download == NULL) {
    GST_WARNING_OBJECT (downloader, "Failed to set src to READY");
    goto quit;
  }

  /* might have been cancelled because of failures in state change */
  if (downloader->priv->cancelled) {
    goto quit;
  }

  if (range_start < 0 && range_end < 0) {
    if (!gst_uri_downloader_set_method (downloader, "HEAD")) {
      GST_WARNING_OBJECT (downloader, "Failed to set HTTP method");
      goto quit;
    }
  } else {
    if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) {
      GST_WARNING_OBJECT (downloader, "Failed to set range");
      goto quit;
    }
  }

  GST_OBJECT_UNLOCK (downloader);
  ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING);
  GST_OBJECT_LOCK (downloader);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    if (downloader->priv->download) {
      g_object_unref (downloader->priv->download);
      downloader->priv->download = NULL;
    }
    goto quit;
  }

  /* might have been cancelled because of failures in state change */
  if (downloader->priv->cancelled) {
    goto quit;
  }

  /* wait until:
   *   - the download succeed (EOS in the src pad)
   *   - the download failed (Error message on the fetcher bus)
   *   - the download was canceled
   */
  GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI %s", uri);
  while (!downloader->priv->cancelled && !downloader->priv->download->completed)
    g_cond_wait (&downloader->priv->cond, GST_OBJECT_GET_LOCK (downloader));

  if (downloader->priv->cancelled) {
    if (downloader->priv->download) {
      g_object_unref (downloader->priv->download);
      downloader->priv->download = NULL;
    }
    goto quit;
  }

  download = downloader->priv->download;
  downloader->priv->download = NULL;
  if (!downloader->priv->got_buffer) {
    if (download->range_start < 0 && download->range_end < 0) {
      /* HEAD request, so we don't expect a response */
    } else {
      g_object_unref (download);
      download = NULL;
      GST_ERROR_OBJECT (downloader, "Didn't retrieve a buffer before EOS");
    }
  }

  if (download != NULL)
    GST_INFO_OBJECT (downloader, "URI fetched successfully");
  else
    GST_INFO_OBJECT (downloader, "Error fetching URI");

quit:
  {
    if (downloader->priv->urisrc) {
      GstPad *pad;
      GstElement *urisrc;

      urisrc = downloader->priv->urisrc;

      GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
          GST_ELEMENT_NAME (urisrc));

      /* remove the bus' sync handler */
      gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL);
      gst_bus_set_flushing (downloader->priv->bus, TRUE);

      /* set the element state to NULL */
      GST_OBJECT_UNLOCK (downloader);
      if (download == NULL) {
        gst_element_set_state (urisrc, GST_STATE_NULL);
      } else {
        GstQuery *query;

        /* Download successfull, let's query the URI */
        query = gst_query_new_uri ();
        if (gst_element_query (urisrc, query)) {
          gst_query_parse_uri (query, &download->uri);
          gst_query_parse_uri_redirection (query, &download->redirect_uri);
          gst_query_parse_uri_redirection_permanent (query,
              &download->redirect_permanent);
        }
        gst_query_unref (query);
        gst_element_set_state (urisrc, GST_STATE_READY);
      }
      GST_OBJECT_LOCK (downloader);
      gst_element_set_bus (urisrc, NULL);

      /* unlink the source element from the internal pad */
      pad = gst_pad_get_peer (downloader->priv->pad);
      if (pad) {
        gst_pad_unlink (pad, downloader->priv->pad);
        gst_object_unref (pad);
      }
    }
    GST_OBJECT_UNLOCK (downloader);

    if (download == NULL) {
      if (!downloader->priv->err) {
        g_set_error (err, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ,
            "Failed to download '%s'", uri);
      } else {
        g_propagate_error (err, downloader->priv->err);
        downloader->priv->err = NULL;
      }
    }

    downloader->priv->cancelled = FALSE;

    g_mutex_unlock (&downloader->priv->download_lock);
    return download;
  }
}
/**
 * gst_uri_downloader_fetch_uri_with_range:
 * @downloader: the #GstUriDownloader
 * @uri: the uri
 * @range_start: the starting byte index
 * @range_end: the final byte index, use -1 for unspecified
 *
 * Returns the downloaded #GstFragment
 */
GstFragment *
gst_uri_downloader_fetch_uri_with_range (GstUriDownloader * downloader,
    const gchar * uri, gint64 range_start, gint64 range_end)
{
  GstStateChangeReturn ret;
  GstFragment *download = NULL;

  GST_DEBUG_OBJECT (downloader, "Fetching URI %s", uri);

  g_mutex_lock (&downloader->priv->download_lock);

  GST_OBJECT_LOCK (downloader);
  if (downloader->priv->cancelled) {
    GST_DEBUG_OBJECT (downloader, "Cancelled, aborting fetch");
    goto quit;
  }

  if (!gst_uri_downloader_set_uri (downloader, uri)) {
    GST_WARNING_OBJECT (downloader, "Failed to set URI");
    goto quit;
  }

  gst_bus_set_flushing (downloader->priv->bus, FALSE);
  downloader->priv->download = gst_fragment_new ();
  GST_OBJECT_UNLOCK (downloader);
  ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_READY);
  GST_OBJECT_LOCK (downloader);
  if (ret == GST_STATE_CHANGE_FAILURE || downloader->priv->download == NULL) {
    GST_WARNING_OBJECT (downloader, "Failed to set src to READY");
    goto quit;
  }

  /* might have been cancelled because of failures in state change */
  if (downloader->priv->cancelled) {
    goto quit;
  }

  if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) {
    GST_WARNING_OBJECT (downloader, "Failed to set range");
    goto quit;
  }

  GST_OBJECT_UNLOCK (downloader);
  ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING);
  GST_OBJECT_LOCK (downloader);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    if (downloader->priv->download) {
      g_object_unref (downloader->priv->download);
      downloader->priv->download = NULL;
    }
    goto quit;
  }

  /* might have been cancelled because of failures in state change */
  if (downloader->priv->cancelled) {
    goto quit;
  }

  /* wait until:
   *   - the download succeed (EOS in the src pad)
   *   - the download failed (Error message on the fetcher bus)
   *   - the download was canceled
   */
  GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI %s", uri);
  while (!downloader->priv->cancelled && !downloader->priv->download->completed)
    g_cond_wait (&downloader->priv->cond, GST_OBJECT_GET_LOCK (downloader));

  if (downloader->priv->cancelled) {
    if (downloader->priv->download) {
      g_object_unref (downloader->priv->download);
      downloader->priv->download = NULL;
    }
    goto quit;
  }

  download = downloader->priv->download;
  downloader->priv->download = NULL;

  if (download != NULL)
    GST_INFO_OBJECT (downloader, "URI fetched successfully");
  else
    GST_INFO_OBJECT (downloader, "Error fetching URI");

quit:
  {
    if (downloader->priv->urisrc) {
      GstPad *pad;
      GstElement *urisrc;

      GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
          GST_ELEMENT_NAME (downloader->priv->urisrc));

      /* remove the bus' sync handler */
      gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL);
      /* unlink the source element from the internal pad */
      pad = gst_pad_get_peer (downloader->priv->pad);
      if (pad) {
        gst_pad_unlink (pad, downloader->priv->pad);
        gst_object_unref (pad);
      }
      urisrc = downloader->priv->urisrc;
      downloader->priv->urisrc = NULL;
      GST_OBJECT_UNLOCK (downloader);

      GST_DEBUG_OBJECT (downloader, "Stopping source element %s",
          GST_ELEMENT_NAME (urisrc));

      /* set the element state to NULL */
      gst_bus_set_flushing (downloader->priv->bus, TRUE);
      gst_element_set_state (urisrc, GST_STATE_NULL);
      gst_element_get_state (urisrc, NULL, NULL, GST_CLOCK_TIME_NONE);
      gst_element_set_bus (urisrc, NULL);
      gst_object_unref (urisrc);
    } else {
      GST_OBJECT_UNLOCK (downloader);
    }

    g_mutex_unlock (&downloader->priv->download_lock);
    return download;
  }
}
static void
test_videoframe_audiolevel_generic (void)
{
  GstElement *alevel;
  GstPad *asink, *vsink, *asrc, *vsrc, *aoutput_sink, *voutput_sink;
  GThread *athread, *vthread;
  GstBus *bus;
  guint i;

  got_eos = FALSE;
  audio_buffer_count = 0;
  video_buffer_count = 0;
  num_msgs = 0;

  g_queue_init (&v_timestamp_q);
  g_queue_init (&msg_timestamp_q);

  alevel = gst_element_factory_make ("videoframe-audiolevel", NULL);
  fail_unless (alevel != NULL);

  bus = gst_bus_new ();
  gst_element_set_bus (alevel, bus);
  gst_bus_set_sync_handler (bus, on_message, NULL, NULL);

  asink = gst_element_get_static_pad (alevel, "asink");
  fail_unless (asink != NULL);

  vsink = gst_element_get_static_pad (alevel, "vsink");
  fail_unless (vsink != NULL);

  asrc = gst_element_get_static_pad (alevel, "asrc");
  aoutput_sink = gst_pad_new ("sink", GST_PAD_SINK);
  fail_unless (aoutput_sink != NULL);
  fail_unless (gst_pad_link (asrc, aoutput_sink) == GST_PAD_LINK_OK);

  vsrc = gst_element_get_static_pad (alevel, "vsrc");
  voutput_sink = gst_pad_new ("sink", GST_PAD_SINK);
  fail_unless (voutput_sink != NULL);
  fail_unless (gst_pad_link (vsrc, voutput_sink) == GST_PAD_LINK_OK);

  gst_pad_set_chain_function (aoutput_sink, output_achain);
  gst_pad_set_event_function (aoutput_sink, output_aevent);

  gst_pad_set_chain_function (voutput_sink, output_vchain);
  gst_pad_set_event_function (voutput_sink, output_vevent);

  gst_pad_set_active (aoutput_sink, TRUE);
  gst_pad_set_active (voutput_sink, TRUE);
  fail_unless (gst_element_set_state (alevel,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);

  athread = g_thread_new ("athread", (GThreadFunc) push_abuffers, asink);
  vthread = g_thread_new ("vthread", (GThreadFunc) push_vbuffers, vsink);

  g_thread_join (vthread);
  g_thread_join (athread);

  fail_unless (got_eos);
  fail_unless_equals_int (audio_buffer_count, n_abuffers);
  fail_unless_equals_int (video_buffer_count, n_vbuffers);
  if (!long_video)
    fail_unless_equals_int (num_msgs, n_vbuffers);

  fail_unless_equals_int (g_queue_get_length (&v_timestamp_q), n_vbuffers);
  /* num_msgs is equal to n_vbuffers except in the case of long_video */
  fail_unless_equals_int (g_queue_get_length (&msg_timestamp_q), num_msgs);

  for (i = 0; i < g_queue_get_length (&msg_timestamp_q); i++) {
    GstClockTime *vt = g_queue_pop_head (&v_timestamp_q);
    GstClockTime *mt = g_queue_pop_head (&msg_timestamp_q);
    fail_unless (vt != NULL);
    fail_unless (mt != NULL);
    if (!video_gaps && !video_overlaps && !early_video)
      fail_unless_equals_uint64 (*vt, *mt);
    g_free (vt);
    g_free (mt);
  }

  /* teardown */
  gst_element_set_state (alevel, GST_STATE_NULL);
  gst_bus_set_flushing (bus, TRUE);
  gst_object_unref (bus);
  g_queue_foreach (&v_timestamp_q, (GFunc) g_free, NULL);
  g_queue_foreach (&msg_timestamp_q, (GFunc) g_free, NULL);
  g_queue_clear (&v_timestamp_q);
  g_queue_clear (&msg_timestamp_q);
  gst_pad_unlink (asrc, aoutput_sink);
  gst_object_unref (asrc);
  gst_pad_unlink (vsrc, voutput_sink);
  gst_object_unref (vsrc);
  gst_object_unref (asink);
  gst_object_unref (vsink);
  gst_pad_set_active (aoutput_sink, FALSE);
  gst_object_unref (aoutput_sink);
  gst_pad_set_active (voutput_sink, FALSE);
  gst_object_unref (voutput_sink);
  gst_object_unref (alevel);
}
Beispiel #20
0
gboolean
gst_uri_downloader_stream_uri (GstUriDownloader * downloader,
    const gchar * uri, gint64 range_start, gint64 range_end,
    GstUriDownloaderChainFunction chain_func, gpointer user_data)
{
  GstStateChangeReturn ret;

  GST_INFO_OBJECT (downloader, "fetching URI %s", uri);

  g_mutex_lock (&downloader->download_lock);
  downloader->chain = chain_func;
  downloader->priv = user_data;
  downloader->eos = FALSE;

  gst_pad_set_active (downloader->pad, TRUE);

  GST_OBJECT_LOCK (downloader);
  if (downloader->cancelled)
    goto quit;

  if (!gst_uri_downloader_set_uri (downloader, uri)) {
    GST_ERROR_OBJECT (downloader, "failed to set URI");
    goto quit;
  }

  gst_bus_set_flushing (downloader->bus, FALSE);
  GST_OBJECT_UNLOCK (downloader);

  /* set to ready state first to allow setting range */
  ret = gst_element_set_state (downloader->urisrc, GST_STATE_READY);

  GST_OBJECT_LOCK (downloader);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    GST_ERROR_OBJECT (downloader, "failed to set src to READY");
    goto quit;
  }

  if (downloader->cancelled)
    goto quit;

  if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) {
    GST_ERROR_OBJECT (downloader, "failed to set range");
    goto quit;
  }

  GST_OBJECT_UNLOCK (downloader);

  ret = gst_element_set_state (downloader->urisrc, GST_STATE_PLAYING);

  GST_OBJECT_LOCK (downloader);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    GST_ERROR_OBJECT (downloader, "failed to set src to PLAYING");
    goto quit;
  }

  if (downloader->cancelled)
    goto quit;

  if (!downloader->eos) {
    /* wait until:
     *   - the download succeed (EOS in the src pad)
     *   - the download failed (Error message on the fetcher bus)
     *   - the download was canceled
     */
    GST_DEBUG_OBJECT (downloader, "waiting to fetch the URI %s", uri);
    g_cond_wait (&downloader->cond, GST_OBJECT_GET_LOCK (downloader));
  }

quit:
  {
    gboolean ret = FALSE;

    if (downloader->cancelled) {
      GST_DEBUG_OBJECT (downloader, "download interrupted");
    } else if (downloader->eos) {
      GST_DEBUG_OBJECT (downloader, "URI fetched successfully");
      ret = TRUE;
    }

    downloader->cancelled = FALSE;
    gst_uri_downloader_stop (downloader);
    GST_OBJECT_UNLOCK (downloader);
    g_mutex_unlock (&downloader->download_lock);

    return ret;
  }
}
static void
run_decoding_test (GstElement * mpg123audiodec, gchar const *filename)
{
  GstBus *bus;
  unsigned int num_input_buffers, num_decoded_buffers;
  gint expected_size;
  GstCaps *out_caps, *caps;
  GstAudioInfo audioinfo;
  GstElement *input_pipeline, *input_appsink;
  int i;
  GstBuffer *outbuffer;

  /* 440 Hz = frequency of sine wave in audio data
   * 44100 Hz = sample rate
   * (44100 / 2) Hz = Nyquist frequency */
  static double const expected_frequency_spot = 440.0 / (44100.0 / 2.0);

  fail_unless (gst_element_set_state (mpg123audiodec,
          GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
      "could not set to playing");
  bus = gst_bus_new ();

  gst_element_set_bus (mpg123audiodec, bus);

  setup_input_pipeline (filename, &input_pipeline, &input_appsink);

  num_input_buffers = 0;
  while (TRUE) {
    GstSample *sample;
    GstBuffer *input_buffer;

    sample = gst_app_sink_pull_sample (GST_APP_SINK (input_appsink));
    if (sample == NULL)
      break;

    fail_unless (GST_IS_SAMPLE (sample));

    input_buffer = gst_sample_get_buffer (sample);
    fail_if (input_buffer == NULL);

    /* This is done to be on the safe side - docs say lifetime of the input buffer
     * depends *solely* on the sample */
    input_buffer = gst_buffer_copy (input_buffer);

    fail_unless_equals_int (gst_pad_push (mysrcpad, input_buffer), GST_FLOW_OK);

    ++num_input_buffers;

    gst_sample_unref (sample);
  }

  num_decoded_buffers = g_list_length (buffers);

  /* check number of decoded buffers */
  fail_unless_equals_int (num_decoded_buffers, num_input_buffers - 2);

  caps = gst_pad_get_current_caps (mysinkpad);
  GST_LOG ("output caps %" GST_PTR_FORMAT, caps);
  fail_unless (gst_audio_info_from_caps (&audioinfo, caps),
      "Getting audio info from caps failed");

  /* check caps */
  out_caps = gst_caps_new_simple ("audio/x-raw",
      "format", G_TYPE_STRING, "S32LE",
      "layout", G_TYPE_STRING, "interleaved",
      "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, NULL);

  fail_unless (gst_caps_is_equal_fixed (caps, out_caps), "Incorrect out caps");

  gst_caps_unref (out_caps);
  gst_caps_unref (caps);

  /* here, test if decoded data is a sine tone, and if the sine frequency is at the
   * right spot in the spectrum */
  for (i = 0; i < num_decoded_buffers; ++i) {
    outbuffer = GST_BUFFER (buffers->data);
    fail_if (outbuffer == NULL, "Invalid buffer retrieved");

    /* MPEG 1 layer 2 uses 1152 samples per frame */
    expected_size = 1152 * GST_AUDIO_INFO_BPF (&audioinfo);
    fail_unless_equals_int (gst_buffer_get_size (outbuffer), expected_size);

    check_main_frequency_spot_S32 (outbuffer, expected_frequency_spot);

    buffers = g_list_remove (buffers, outbuffer);
    gst_buffer_unref (outbuffer);
    outbuffer = NULL;
  }

  g_list_free (buffers);
  buffers = NULL;

  cleanup_input_pipeline (input_pipeline);
  gst_bus_set_flushing (bus, TRUE);
  gst_element_set_bus (mpg123audiodec, NULL);
  gst_object_unref (GST_OBJECT (bus));
}
gboolean
gst_device_monitor_start (GstDeviceMonitor * monitor)
{
    guint cookie, i;
    GList *pending = NULL, *started = NULL, *removed = NULL;

    g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE);

    GST_OBJECT_LOCK (monitor);

    if (monitor->priv->filters->len == 0) {
        GST_OBJECT_UNLOCK (monitor);
        GST_WARNING_OBJECT (monitor, "No filters have been set, will expose all "
                            "devices found");
        gst_device_monitor_add_filter (monitor, NULL, NULL);
        GST_OBJECT_LOCK (monitor);
    }

    if (monitor->priv->providers->len == 0) {
        GST_OBJECT_UNLOCK (monitor);
        GST_WARNING_OBJECT (monitor, "No providers match the current filters");
        return FALSE;
    }

    gst_bus_set_flushing (monitor->priv->bus, FALSE);

again:
    cookie = monitor->priv->cookie;

    g_list_free_full (pending, gst_object_unref);
    pending = NULL;
    removed = started;
    started = NULL;

    for (i = 0; i < monitor->priv->providers->len; i++) {
        GstDeviceProvider *provider;
        GList *find;

        provider = g_ptr_array_index (monitor->priv->providers, i);

        find = g_list_find (removed, provider);
        if (find) {
            /* this was already started, move to started list */
            removed = g_list_remove_link (removed, find);
            started = g_list_concat (started, find);
        } else {
            /* not started, add to pending list */
            pending = g_list_append (pending, gst_object_ref (provider));
        }
    }
    g_list_free_full (removed, gst_object_unref);
    removed = NULL;

    while (pending) {
        GstDeviceProvider *provider = pending->data;

        if (gst_device_provider_can_monitor (provider)) {
            GST_OBJECT_UNLOCK (monitor);

            if (!gst_device_provider_start (provider))
                goto start_failed;

            GST_OBJECT_LOCK (monitor);
        }
        started = g_list_prepend (started, provider);
        pending = g_list_delete_link (pending, pending);

        if (monitor->priv->cookie != cookie)
            goto again;
    }
    monitor->priv->started = TRUE;
    GST_OBJECT_UNLOCK (monitor);

    g_list_free_full (started, gst_object_unref);

    return TRUE;

start_failed:
    {
        GST_OBJECT_LOCK (monitor);
        gst_bus_set_flushing (monitor->priv->bus, TRUE);
        GST_OBJECT_UNLOCK (monitor);

        while (started) {
            GstDeviceProvider *provider = started->data;

            gst_device_provider_stop (provider);
            gst_object_unref (provider);

            started = g_list_delete_link (started, started);
        }
        return FALSE;
    }
}
Beispiel #23
0
gboolean check_missing_plugins(GstEncodingProfile *profile,
			       char ***details,
			       char ***descriptions)
{
	GstElement *encodebin;
	GstBus *bus;
	GstPad *pad;
	gboolean ret;

	ret = FALSE;

	encodebin = gst_element_factory_make("encodebin", NULL);
	if (encodebin == NULL) {
		g_warning("Unable to create encodebin");
		return TRUE;
	}

	bus = gst_bus_new();
	gst_element_set_bus(encodebin, bus);
	gst_bus_set_flushing(bus, FALSE);		/* necessary? */

	g_object_set(encodebin, "profile", profile, NULL);
	pad = gst_element_get_static_pad(encodebin, "audio_0");
	if (pad == NULL) {
		GstMessage *message;
		GList *messages = NULL;
		GList *m;

		message = gst_bus_pop(bus);
		while (message != NULL) {
			if (gst_is_missing_plugin_message(message))
				messages = g_list_append(messages, message);
			else
				gst_message_unref(message);
			message = gst_bus_pop(bus);
		}

		if (messages != NULL) {
			int i;

			if (details != NULL)
				*details = g_new0(char *, g_list_length(messages)+1);
			if (descriptions != NULL)
				*descriptions = g_new0(char *, g_list_length(messages)+1);
			i = 0;
			for (m = messages; m != NULL; m = m->next) {
				char *str;
				if (details != NULL) {
					str = gst_missing_plugin_message_get_installer_detail(m->data);
					(*details)[i] = str;
				}
				if (descriptions != NULL) {
					str = gst_missing_plugin_message_get_description(m->data);
					(*descriptions)[i] = str;
				}
				i++;
			}

			ret = TRUE;
			g_list_foreach(messages,(GFunc)gst_message_unref, NULL);
			g_list_free(messages);
		}