static GstElement *
kms_recorder_endpoint_get_sink_fallback (KmsRecorderEndpoint * self)
{
  GstElement *sink = NULL;
  gchar *prot;

  prot = gst_uri_get_protocol (KMS_URI_ENDPOINT (self)->uri);

  if ((g_strcmp0 (prot, HTTP_PROTO) == 0)
      || (g_strcmp0 (prot, HTTPS_PROTO) == 0)) {

    if (kms_is_valid_uri (KMS_URI_ENDPOINT (self)->uri)) {
      /* We use souphttpclientsink */
      sink = gst_element_factory_make ("curlhttpsink", NULL);
      g_object_set (sink, "blocksize", MEGA_BYTES (1), "qos", FALSE,
          "async", FALSE, NULL);
    } else {
      GST_ERROR ("URL not valid");
    }

  }

  g_free (prot);

  /* Add more if required */
  return sink;
}
Exemplo n.º 2
0
/**
 * Set the context attribute for URI
 *
 * \param me		element context whose attribute is being set
 * \param uri		the value to which the attribute should be set
 * \return true if the value was set, false if some error occured
 */
static gboolean
gst_ccnxsrc_set_uri (Gstccnxsrc * me, const gchar * uri)
{
  gchar *protocol;
  gchar *location;
  gchar *colptr;

  /* cast to the proper type, then do some basic checks */
  /* we are specific as to what protocol can be used in the URI */
  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "ccnx") != 0)
    goto wrong_protocol;
  g_free (protocol);

  location = gst_uri_get_location (uri);
  if (!location)
    return FALSE;
  colptr = strrchr (location, ':');
  g_free (location);

  /* Free the old value before setting to the new attribute value */
  g_free (me->uri);
  me->uri = g_strdup (uri);

  return TRUE;

  /* ERRORS */
wrong_protocol:
  {
    GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL),
        ("error parsing uri %s: wrong protocol (%s != ccnx)", uri, protocol));
    g_free (protocol);
    return FALSE;
  }
}
Exemplo n.º 3
0
static gboolean
cdaudio_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gchar *protocol, *location;
  gboolean ret;

  ret = TRUE;

  //GstCDAudio *cdaudio = GST_CDAUDIO(handler);

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "cd") != 0)
    goto wrong_protocol;

  g_free (protocol);

  location = gst_uri_get_location (uri);
  /*
     cdaudio->uri_track = strtol(location,NULL,10);
     if (cdaudio->uri_track > 0) {
     cdaudio->seek_request = cdaudio->uri_track;
     }
   */
  g_free (location);

  return ret;

  /* ERRORS */
wrong_protocol:
  {
    g_free (protocol);
    return FALSE;
  }
}
static GstElement *
kms_recorder_end_point_get_sink_fallback (KmsRecorderEndPoint * self)
{
  GstElement *sink = NULL;
  gchar *prot;

  prot = gst_uri_get_protocol (KMS_URI_END_POINT (self)->uri);

  if ((g_strcmp0 (prot, HTTP_PROTO) == 0)
      || (g_strcmp0 (prot, HTTPS_PROTO) == 0)) {
    SoupSession *ss;

    if (kms_is_valid_uri (KMS_URI_END_POINT (self)->uri)) {
      /* We use souphttpclientsink */
      sink = gst_element_factory_make ("souphttpclientsink", NULL);
      g_object_set (sink, "blocksize", MEGA_BYTES (1), NULL);
      ss = soup_session_new_with_options ("timeout", HTTP_TIMEOUT,
          "ssl-strict", FALSE, NULL);
      g_object_set (G_OBJECT (sink), "session", ss, NULL);
    } else {
      GST_ERROR ("URL not valid");
    }

  }
  /* Add more if required */
  return sink;
}
Exemplo n.º 5
0
static gboolean
dvb_base_bin_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gboolean ret;
  gchar *protocol;
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (handler);

  protocol = gst_uri_get_protocol (uri);

  if (strcmp (protocol, "dvb") != 0) {
    ret = FALSE;
  } else {
    gchar *location = gst_uri_get_location (uri);

    if (location != NULL) {
      ret = set_properties_for_channel (G_OBJECT (dvbbasebin), location);
      g_free (location);
    } else
      ret = FALSE;
  }

  /* here is where we parse channels.conf */
  g_free (protocol);

  return ret;
}
static gboolean
gst_hdv1394src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
                            GError ** error)
{
    gchar *protocol, *location;
    gboolean ret = TRUE;
    GstHDV1394Src *gst_hdv1394src = GST_HDV1394SRC (handler);

    protocol = gst_uri_get_protocol (uri);
    if (strcmp (protocol, "hdv") != 0) {
        g_free (protocol);
        g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
                     "Invalid HDV URI");
        return FALSE;
    }
    g_free (protocol);

    location = gst_uri_get_location (uri);
    if (location && *location != '\0')
        gst_hdv1394src->port = strtol (location, NULL, 10);
    else
        gst_hdv1394src->port = DEFAULT_PORT;
    g_free (location);
    g_free (gst_hdv1394src->uri);
    gst_hdv1394src->uri = g_strdup_printf ("hdv://%d", gst_hdv1394src->port);

    return ret;
}
Exemplo n.º 7
0
static gboolean
gst_fd_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gchar *protocol;
  GstFdSrc *src = GST_FD_SRC (handler);
  gint fd;

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "fd") != 0) {
    g_free (protocol);
    return FALSE;
  }
  g_free (protocol);

  if (sscanf (uri, "fd://%d", &fd) != 1 || fd < 0)
    return FALSE;

  src->new_fd = fd;

  GST_OBJECT_LOCK (src);
  if (GST_STATE (GST_ELEMENT (src)) <= GST_STATE_READY) {
    gst_fd_src_update_fd (src);
  }
  GST_OBJECT_UNLOCK (src);

  return TRUE;
}
Exemplo n.º 8
0
static gboolean
make_source (GstUriTranscodeBin * self)
{
  GError *err = NULL;

  if (!gst_uri_is_valid (self->source_uri))
    goto invalid_uri;

  self->src = gst_element_make_from_uri (GST_URI_SRC, self->source_uri,
      "src", &err);
  if (!self->src)
    goto no_sink;

  gst_bin_add (GST_BIN (self), self->src);

  if (!gst_element_link (self->src, self->transcodebin))
    return FALSE;

  return TRUE;

invalid_uri:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
        ("Invalid URI \"%s\".", self->source_uri), (NULL));
    g_clear_error (&err);
    return FALSE;
  }

no_sink:
  {
    /* whoops, could not create the source element, dig a little deeper to
     * figure out what might be wrong. */
    if (err != NULL && err->code == GST_URI_ERROR_UNSUPPORTED_PROTOCOL) {
      gchar *prot;

      prot = gst_uri_get_protocol (self->source_uri);
      if (prot == NULL)
        goto invalid_uri;

      gst_element_post_message (GST_ELEMENT_CAST (self),
          gst_missing_uri_source_message_new (GST_ELEMENT (self), prot));

      GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN,
          ("No URI handler implemented for \"%s\".", prot), (NULL));

      g_free (prot);
    } else {
      GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
          ("%s", (err) ? err->message : "URI was not accepted by any element"),
          ("No element accepted URI '%s'", self->dest_uri));
    }

    g_clear_error (&err);

    return FALSE;
  }
}
Exemplo n.º 9
0
static gboolean
gst_spot_src_set_spotifyuri (GstSpotSrc * spot, const gchar * uri)
{
  GstState state;
  gchar *protocol = NULL;
  gchar *location;

  /* hopefully not possible */
  g_assert (uri);

  /* the element must be stopped in order to do this */
  state = GST_STATE (spot);
  if (state != GST_STATE_READY && state != GST_STATE_NULL) {
    GST_WARNING_OBJECT (spot, "Setting spotify_uri in wrong state");
    goto wrong_state;
  }

  if (!gst_uri_is_valid (uri)) {
    GST_WARNING_OBJECT (spot, "Invalid URI '%s' for spotsrc", uri);
    goto invalid_uri;
  }

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "spotify") != 0) {
     GST_WARNING_OBJECT (spot, "Setting spotify_uri with wrong protocol");
     goto wrong_protocol;
  }
  g_free (protocol);

  location = gst_uri_get_location (uri);
  if (!location) {
    GST_WARNING_OBJECT (spot, "Setting spotify_uri with wrong/no location");
    goto wrong_location;
  }

  /* we store the spotify_uri as received by the application. On Windoes this
   * should be UTF8 */
  g_free (GST_SPOT_SRC_URI (spot));

  GST_SPOT_SRC_URI (spot) = g_strdup (uri);
  
  g_object_notify (G_OBJECT (spot), "uri"); /* why? */
  gst_uri_handler_new_uri (GST_URI_HANDLER (spot), spot->uri);

  return TRUE;

  /* ERROR */
invalid_uri:

wrong_protocol:
  g_free (protocol);
wrong_state:
wrong_location:
  return FALSE;
}
static gboolean
hls_test_start (InsanityTest * test)
{
  GValue uri = { 0 };
  const char *protocol;
  gchar *playlist, *hlsuri, *source_folder, *folder_uri;
  SoupServer *ssl_server;
  guint port, ssl_port;

  if (!insanity_test_get_argument (test, "uri", &uri))
    return FALSE;
  if (!strcmp (g_value_get_string (&uri), "")) {
    insanity_test_validate_checklist_item (test, "uri-is-file", FALSE,
        "No URI to test on");
    g_value_unset (&uri);
    return FALSE;
  }

  if (!gst_uri_is_valid (g_value_get_string (&uri))) {
    insanity_test_validate_checklist_item (test, "uri-is-file", FALSE, NULL);
    g_value_unset (&uri);
    return FALSE;
  }
  protocol = gst_uri_get_protocol (g_value_get_string (&uri));
  if (!protocol || g_ascii_strcasecmp (protocol, "file")) {
    insanity_test_validate_checklist_item (test, "uri-is-file", FALSE, NULL);
    g_value_unset (&uri);
    return FALSE;
  }
  insanity_test_validate_checklist_item (test, "uri-is-file", TRUE, NULL);
  source_folder = gst_uri_get_location (g_value_get_string (&uri));
  folder_uri = g_path_get_dirname (source_folder);
  insanity_http_server_set_source_folder (glob_server, folder_uri);
  g_value_unset (&uri);

  port = insanity_http_server_get_port (glob_server);
  ssl_port = insanity_http_server_get_ssl_port (glob_server);
  ssl_server = insanity_http_server_get_soup_ssl_server (glob_server);
  playlist = g_path_get_basename (source_folder);
  if (ssl_server) {
    hlsuri = g_strdup_printf ("http://127.0.0.1:%u/%s", ssl_port, playlist);
  } else {
    hlsuri = g_strdup_printf ("http://127.0.0.1:%u/%s", port, playlist);
  }
  g_free (source_folder);
  g_object_set (glob_pipeline, "uri", hlsuri, NULL);
  g_free (hlsuri);

  glob_validate_on_playing = NULL;
  glob_done_hls = FALSE;
  glob_duration = GST_CLOCK_TIME_NONE;

  return TRUE;
}
Exemplo n.º 11
0
static gboolean
gst_app_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gchar *protocol;
  gboolean ret;

  protocol = gst_uri_get_protocol (uri);
  ret = !strcmp (protocol, "appsrc");
  g_free (protocol);

  return ret;
}
Exemplo n.º 12
0
static gboolean
gst_mms_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gchar *protocol;
  GstMMS *src = GST_MMS (handler);

  protocol = gst_uri_get_protocol (uri);
  if ((strcmp (protocol, "mms") != 0) && (strcmp (protocol, "mmsh") != 0)) {
    g_free (protocol);
    return FALSE;
  }
  g_free (protocol);
  g_object_set (src, "location", uri, NULL);

  return TRUE;
}
Exemplo n.º 13
0
static gboolean
gst_file_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gchar *protocol, *location;
  gboolean ret;
  GstFileSrc *src = GST_FILE_SRC (handler);

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "file") != 0) {
    g_free (protocol);
    return FALSE;
  }
  g_free (protocol);

  /* allow file://localhost/foo/bar by stripping localhost but fail
   * for every other hostname */
  if (g_str_has_prefix (uri, "file://localhost/")) {
    char *tmp;

    /* 16 == strlen ("file://localhost") */
    tmp = g_strconcat ("file://", uri + 16, NULL);
    /* we use gst_uri_get_location() although we already have the
     * "location" with uri + 16 because it provides unescaping */
    location = gst_uri_get_location (tmp);
    g_free (tmp);
  } else if (strcmp (uri, "file://") == 0) {
    /* Special case for "file://" as this is used by some applications
     *  to test with gst_element_make_from_uri if there's an element
     *  that supports the URI protocol. */
    gst_file_src_set_location (src, NULL);
    return TRUE;
  } else {
    location = gst_uri_get_location (uri);
  }

  if (!location)
    return FALSE;
  if (!g_path_is_absolute (location)) {
    g_free (location);
    return FALSE;
  }

  ret = gst_file_src_set_location (src, location);
  g_free (location);

  return ret;
}
Exemplo n.º 14
0
static gchar *
gst_mms_src_make_valid_uri (const gchar * uri)
{
  gchar *protocol;
  const gchar *colon, *tmp;
  gsize len;

  if (!uri || !gst_uri_is_valid (uri))
    return NULL;

  protocol = gst_uri_get_protocol (uri);

  if ((strcmp (protocol, "mms") != 0) && (strcmp (protocol, "mmsh") != 0) &&
      (strcmp (protocol, "mmst") != 0) && (strcmp (protocol, "mmsu") != 0)) {
    g_free (protocol);
    return FALSE;
  }
  g_free (protocol);

  colon = strstr (uri, "://");
  if (!colon)
    return NULL;

  tmp = colon + 3;
  len = strlen (tmp);
  if (len == 0)
    return NULL;

  /* libmms segfaults if there's no hostname or
   * no / after the hostname
   */
  colon = strstr (tmp, "/");
  if (colon == tmp)
    return NULL;

  if (strstr (tmp, "/") == NULL) {
    gchar *ret;

    len = strlen (uri);
    ret = g_malloc0 (len + 2);
    memcpy (ret, uri, len);
    ret[len] = '/';
    return ret;
  } else {
    return g_strdup (uri);
  }
}
Exemplo n.º 15
0
static gboolean
gst_fd_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gchar *protocol, *q;
  GstFdSrc *src = GST_FD_SRC (handler);
  gint fd;
  guint64 size = -1;

  GST_INFO_OBJECT (src, "checking uri %s", uri);

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "fd") != 0) {
    g_free (protocol);
    return FALSE;
  }
  g_free (protocol);

  if (sscanf (uri, "fd://%d", &fd) != 1 || fd < 0)
    return FALSE;

  if ((q = g_strstr_len (uri, -1, "?"))) {
    gchar *sp;

    GST_INFO_OBJECT (src, "found ?");

    if ((sp = g_strstr_len (q, -1, "size="))) {
      if (sscanf (sp, "size=%" G_GUINT64_FORMAT, &size) != 1) {
        GST_INFO_OBJECT (src, "parsing size failed");
        size = -1;
      } else {
        GST_INFO_OBJECT (src, "found size %" G_GUINT64_FORMAT, size);
      }
    }
  }

  src->new_fd = fd;

  GST_OBJECT_LOCK (src);
  if (GST_STATE (GST_ELEMENT (src)) <= GST_STATE_READY) {
    gst_fd_src_update_fd (src, size);
  }
  GST_OBJECT_UNLOCK (src);

  return TRUE;
}
Exemplo n.º 16
0
static gboolean
gst_udpsink_set_uri (GstUDPSink * sink, const gchar * uri)
{
  gchar *protocol;
  gchar *location;
  gchar *colptr;

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "udp") != 0)
    goto wrong_protocol;
  g_free (protocol);

  location = gst_uri_get_location (uri);
  if (!location)
    return FALSE;
  colptr = strstr (location, ":");

  gst_multiudpsink_remove (GST_MULTIUDPSINK (sink), sink->host, sink->port);

  if (colptr != NULL) {
    g_free (sink->host);
    sink->host = g_strndup (location, colptr - location);
    sink->port = atoi (colptr + 1);
  } else {
    g_free (sink->host);
    sink->host = g_strdup (location);
    sink->port = UDP_DEFAULT_PORT;
  }
  g_free (location);

  gst_multiudpsink_add (GST_MULTIUDPSINK (sink), sink->host, sink->port);

  gst_udpsink_update_uri (sink);

  return TRUE;

  /* ERRORS */
wrong_protocol:
  {
    g_free (protocol);
    GST_ELEMENT_ERROR (sink, RESOURCE, READ, (NULL),
        ("error parsing uri %s: wrong protocol (%s != udp)", uri, protocol));
    return FALSE;
  }
}
Exemplo n.º 17
0
static gboolean
gst_fd_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  gchar *protocol;
  GstFdSink *sink = GST_FD_SINK (handler);
  gint fd;

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "fd") != 0) {
    g_free (protocol);
    return FALSE;
  }
  g_free (protocol);

  if (sscanf (uri, "fd://%d", &fd) != 1)
    return FALSE;

  return gst_fd_sink_update_fd (sink, fd);
}
Exemplo n.º 18
0
gboolean
ges_formatter_can_save_uri (const gchar * uri)
{
  if (!(gst_uri_is_valid (uri))) {
    GST_ERROR ("%s invalid uri!", uri);
    return FALSE;
  }

  if (!(gst_uri_has_protocol (uri, "file"))) {
    gchar *proto = gst_uri_get_protocol (uri);
    GST_ERROR ("Unspported protocol '%s'", proto);
    g_free (proto);
    return FALSE;
  }

  /* TODO: implement file format registry */
  /* TODO: search through the registry and chose a GESFormatter class that can
   * handle the URI.*/

  return TRUE;
}
Exemplo n.º 19
0
static void
kms_recorder_endpoint_create_parent_directories (KmsRecorderEndpoint * self)
{
  const gchar *uri = KMS_URI_ENDPOINT (self)->uri;
  gchar *protocol = gst_uri_get_protocol (uri);

  if (g_strcmp0 (protocol, "file") == 0) {
    gchar *file = gst_uri_get_location (uri);
    gchar *dir = g_path_get_dirname (file);

    // Try to create directory
    if (g_mkdir_with_parents (dir, ALLPERMS) != 0) {
      GST_WARNING_OBJECT (self, "Directory %s could not be created", dir);
    }

    g_free (file);
    g_free (dir);
  }

  g_free (protocol);
}
static gboolean
gst_espeak_uri_set_uri (GstURIHandler * handler, const gchar * uri) {
    gchar *protocol, *text;
    gboolean ret;

    protocol = gst_uri_get_protocol (uri);
    ret = strcmp (protocol, "espeak") == 0;
    g_free (protocol);
    if (!ret)
        return FALSE;

    text = gst_uri_get_location (uri);

    if (!text)
        return FALSE;

    gst_espeak_set_text (GST_ESPEAK (handler), text);
    g_free (text);

    return TRUE;
}
Exemplo n.º 21
0
/**
 * Set the context attribute for URI
 *
 * \param me		element context whose attribute is being set
 * \param gv		the value to which the attribute should be set
 * \return true if the value was set, false if some error occured
 */
static gboolean
gst_ccnxsink_set_uri (Gstccnxsink * me, const GValue * gv)
{
  gchar *protocol;
  const gchar *uri;

  /* cast to the proper type, then do some basic checks */
  uri = g_value_get_string (gv);
  GST_DEBUG ("CCNxSink: setting uri: %s\n", uri);

  if (NULL == uri) {
    g_free (me->uri);
    me->uri = g_strdup (CCNX_DEFAULT_URI);
    return TRUE;
  }

  /* we are specific as to what protocol can be used in the URI */
  protocol = gst_uri_get_protocol (uri);
  if (!protocol)
    goto wrong_protocol;
  if (strcmp (protocol, "ccnx") != 0)
    goto wrong_protocol;
  g_free (protocol);

  /* Free the old value before setting to the new attribute value */
  g_free (me->uri);
  me->uri = g_strdup (uri);

  return TRUE;

  /* ERRORS */
wrong_protocol:
  {
    GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL),
        ("error parsing uri %s: wrong protocol (%s != ccnx)", uri, protocol));
    g_free (protocol);
    return FALSE;
  }
}
Exemplo n.º 22
0
/*!
 * \brief OpenIMAJCapGStreamer::open Open the given file with gstreamer
 * \param type CvCapture type. One of CAP_GSTREAMER_*
 * \param filename Filename to open in case of CAP_GSTREAMER_FILE
 * \return boolean. Specifies if opening was succesful.
 *
 * In case of CAP_GSTREAMER_V4L(2), a pipelin is constructed as follows:
 *    v4l2src ! autoconvert ! appsink
 *
 *
 * The 'filename' parameter is not limited to filesystem paths, and may be one of the following:
 *
 *  - a normal filesystem path:
 *        e.g. video.avi or /path/to/video.avi or C:\\video.avi
 *  - an uri:
 *        e.g. file:///path/to/video.avi or rtsp:///path/to/stream.asf
 *  - a gstreamer pipeline description:
 *        e.g. videotestsrc ! videoconvert ! appsink
 *        the appsink name should be either 'appsink0' (the default) or 'opencvsink'
 *
 *  When dealing with a file, OpenIMAJCapGStreamer will not drop frames if the grabbing interval
 *  larger than the framerate period. (Unlike the uri or manual pipeline description, which assume
 *  a live source)
 *
 *  The pipeline will only be started whenever the first frame is grabbed. Setting pipeline properties
 *  is really slow if we need to restart the pipeline over and over again.
 *
 */
bool OpenIMAJCapGStreamer::open(const char* filename )
{
    if(!isInited) {
        //FIXME: threadsafety
        gst_init (NULL, NULL);
        isInited = true;
    }

    
    bool stream = false;
    bool manualpipeline = false;
    char *uri = NULL;
    uridecodebin = NULL;
    
    // test if we have a valid uri. If so, open it with an uridecodebin
    // else, we might have a file or a manual pipeline.
    // if gstreamer cannot parse the manual pipeline, we assume we were given and
    // ordinary file path.
    if(!gst_uri_is_valid(filename))
    {
        uri = realpath(filename, NULL);
        stream = false;
        if(uri)
        {
            uri = g_filename_to_uri(uri, NULL, NULL);
            if(!uri) {
                WARN("GStreamer: Error opening file\n");
                close();
                return false;
            }
        }
        else
        {
            GError *err = NULL;
            uridecodebin = gst_parse_launch(filename, &err);
            if(!uridecodebin) {
                //fprintf(stderr, "GStreamer: Error opening bin: %s\n", err->message);
                //close();
                return false;
            }
            stream = true;
            manualpipeline = true;
        }
    } else {
        stream = true;
        uri = g_strdup(filename);
    }
    
    bool element_from_uri = false;
    if(!uridecodebin)
    {
        // At this writing, the v4l2 element (and maybe others too) does not support caps renegotiation.
        // This means that we cannot use an uridecodebin when dealing with v4l2, since setting
        // capture properties will not work.
        // The solution (probably only until gstreamer 1.2) is to make an element from uri when dealing with v4l2.
        gchar * protocol = gst_uri_get_protocol(uri);
        if (!strcasecmp(protocol , "v4l2"))
        {
            uridecodebin = gst_element_make_from_uri(GST_URI_SRC, uri, "src", NULL);

            element_from_uri = true;
        }else{
            uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
            g_object_set(G_OBJECT(uridecodebin),"uri",uri, NULL);
        }
        g_free(protocol);
        
        if(!uridecodebin) {
            //fprintf(stderr, "GStreamer: Error opening bin: %s\n", err->message);
            close();
            return false;
        }
    }
    
    if(manualpipeline)
    {
        GstIterator *it = NULL;
        it = gst_bin_iterate_sinks (GST_BIN(uridecodebin));
        
        gboolean done = FALSE;
        GstElement *element = NULL;
        gchar* name = NULL;
        GValue value = G_VALUE_INIT;
        
        while (!done) {
            switch (gst_iterator_next (it, &value)) {
                case GST_ITERATOR_OK:
                    element = GST_ELEMENT (g_value_get_object (&value));
                    name = gst_element_get_name(element);
                    if (name){
                        if(strstr(name, "opencvsink") != NULL || strstr(name, "appsink") != NULL) {
                            sink = GST_ELEMENT ( gst_object_ref (element) );
                            done = TRUE;
                        }
                        g_free(name);
                    }
                    g_value_unset (&value);
                    
                    break;
                case GST_ITERATOR_RESYNC:
                    gst_iterator_resync (it);
                    break;
                case GST_ITERATOR_ERROR:
                case GST_ITERATOR_DONE:
                    done = TRUE;
                    break;
            }
        }
        gst_iterator_free (it);
        
        
        if (!sink){
            //ERROR(1, "GStreamer: cannot find appsink in manual pipeline\n");
            return false;
        }
        
        pipeline = uridecodebin;
    }
    else
    {
        pipeline = gst_pipeline_new (NULL);
        // videoconvert (in 0.10: ffmpegcolorspace) automatically selects the correct colorspace
        // conversion based on caps.
        color = gst_element_factory_make(COLOR_ELEM, NULL);
        sink = gst_element_factory_make("appsink", NULL);
        
        gst_bin_add_many(GST_BIN(pipeline), uridecodebin, color, sink, NULL);
        
        if(element_from_uri) {
            if(!gst_element_link(uridecodebin, color)) {
                //ERROR(1, "GStreamer: cannot link color -> sink\n");
                gst_object_unref(pipeline);
                return false;
            }
        }else{
            g_signal_connect(uridecodebin, "pad-added", G_CALLBACK(newPad), color);
        }
        
        if(!gst_element_link(color, sink)) {
            //ERROR(1, "GStreamer: cannot link color -> sink\n");
            gst_object_unref(pipeline);
            return false;
        }
    }
    
    //TODO: is 1 single buffer really high enough?
    gst_app_sink_set_max_buffers (GST_APP_SINK(sink), 1);
    gst_app_sink_set_drop (GST_APP_SINK(sink), stream);
    //do not emit signals: all calls will be synchronous and blocking
    gst_app_sink_set_emit_signals (GST_APP_SINK(sink), 0);
    
    // support 1 and 3 channel 8 bit data, as well as bayer (also  1 channel, 8bit)
    caps = gst_caps_from_string("video/x-raw, format=(string){BGR, GRAY8}; video/x-bayer,format=(string){rggb,bggr,grbg,gbrg}");
    gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
    gst_caps_unref(caps);
    
    //we do not start recording here just yet.
    // the user probably wants to set capture properties first, so start recording whenever the first frame is requested
    
    return true;
}
Exemplo n.º 23
0
static gboolean
rsn_dvdbin_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  RsnDvdBin *dvdbin = RESINDVDBIN (handler);
  gboolean ret;
  gchar *protocol, *location;

  protocol = gst_uri_get_protocol (uri);

  ret = (protocol && !strcmp (protocol, "dvd")) ? TRUE : FALSE;

  g_free (protocol);
  protocol = NULL;

  if (!ret)
    return ret;

  location = gst_uri_get_location (uri);
  if (!location)
    return ret;

  /*
   * URI structure: dvd:///path/to/device
   */
  if (g_str_has_prefix (uri, "dvd://")) {
    g_free (dvdbin->device);
    if (strlen (uri) > 6)
      dvdbin->device = g_strdup (uri + 6);
    else
      dvdbin->device = g_strdup (DEFAULT_DEVICE);
  }
#if 0
  /*
   * Parse out the new t/c/a and seek to them
   */
  {
    gchar **strs;
    gchar **strcur;
    gint pos = 0;

    strcur = strs = g_strsplit (location, ",", 0);
    while (strcur && *strcur) {
      gint val;

      if (!sscanf (*strcur, "%d", &val))
        break;

      switch (pos) {
        case 0:
          if (val != dvdbin->uri_title) {
            dvdbin->uri_title = val;
            dvdbin->new_seek = TRUE;
          }
          break;
        case 1:
          if (val != dvdbin->uri_chapter) {
            dvdbin->uri_chapter = val;
            dvdbin->new_seek = TRUE;
          }
          break;
        case 2:
          dvdbin->uri_angle = val;
          break;
      }

      strcur++;
      pos++;
    }

    g_strfreev (strs);
  }
#endif

  g_free (location);

  return ret;
}
Exemplo n.º 24
0
static gboolean
gst_vcdsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
{
  GstVCDSrc *src = GST_VCDSRC (handler);
  gchar *protocol;
  gchar *location = NULL;
  gint tracknr;

  GST_DEBUG_OBJECT (src, "setting uri '%s'", uri);

  protocol = gst_uri_get_protocol (uri);

  if (protocol == NULL || strcmp (protocol, "vcd"))
    goto wrong_protocol;

  GST_DEBUG_OBJECT (src, "have protocol '%s'", protocol);
  g_free (protocol);

  /* parse out the track in the location */
  if (!(location = gst_uri_get_location (uri)))
    goto no_location;

  GST_DEBUG_OBJECT (src, "have location '%s'", location);

  if (*location == '\0') {
    /* empty location selects track 1 */
    tracknr = 1;
  } else {
    /* scan the track number */
    if (sscanf (location, "%d", &tracknr) != 1)
      goto invalid_location;

    if (tracknr < 1)
      goto invalid_location;
  }

  GST_OBJECT_LOCK (src);
  src->track = tracknr;
  GST_DEBUG_OBJECT (src, "configured track %d", src->track);
  GST_OBJECT_UNLOCK (src);

  g_free (location);

  return TRUE;

  /* ERRORS */
wrong_protocol:
  {
    GST_ERROR_OBJECT (src, "wrong protocol %s specified",
        GST_STR_NULL (protocol));
    g_free (protocol);
    return FALSE;
  }
no_location:
  {
    GST_ERROR_OBJECT (src, "no location specified");
    return FALSE;
  }
invalid_location:
  {
    GST_ERROR_OBJECT (src, "Invalid location %s in URI '%s'", location, uri);
    g_free (location);
    return FALSE;
  }
}
Exemplo n.º 25
0
static gboolean
gst_uri_downloader_set_uri (GstUriDownloader * downloader, const gchar * uri,
    const gchar * referer, gboolean compress, gboolean refresh,
    gboolean allow_cache)
{
  GstPad *pad;
  GObjectClass *gobject_class;

  if (!gst_uri_is_valid (uri))
    return FALSE;

  if (downloader->priv->urisrc) {
    gchar *old_protocol, *new_protocol;
    gchar *old_uri;

    old_uri =
        gst_uri_handler_get_uri (GST_URI_HANDLER (downloader->priv->urisrc));
    old_protocol = gst_uri_get_protocol (old_uri);
    new_protocol = gst_uri_get_protocol (uri);

    if (!g_str_equal (old_protocol, new_protocol)) {
      gst_element_set_state (downloader->priv->urisrc, GST_STATE_NULL);
      gst_object_unref (downloader->priv->urisrc);
      downloader->priv->urisrc = NULL;
      GST_DEBUG_OBJECT (downloader, "Can't re-use old source element");
    } else {
      GError *err = NULL;

      GST_DEBUG_OBJECT (downloader, "Re-using old source element");
      if (!gst_uri_handler_set_uri (GST_URI_HANDLER (downloader->priv->urisrc),
              uri, &err)) {
        GST_DEBUG_OBJECT (downloader, "Failed to re-use old source element: %s",
            err->message);
        g_clear_error (&err);
        gst_element_set_state (downloader->priv->urisrc, GST_STATE_NULL);
        gst_object_unref (downloader->priv->urisrc);
        downloader->priv->urisrc = NULL;
      }
    }
    g_free (old_uri);
    g_free (old_protocol);
    g_free (new_protocol);
  }

  if (!downloader->priv->urisrc) {
    GST_DEBUG_OBJECT (downloader, "Creating source element for the URI:%s",
        uri);
    downloader->priv->urisrc =
        gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
    if (!downloader->priv->urisrc)
      return FALSE;
  }

  gobject_class = G_OBJECT_GET_CLASS (downloader->priv->urisrc);
  if (g_object_class_find_property (gobject_class, "compress"))
    g_object_set (downloader->priv->urisrc, "compress", compress, NULL);
  if (g_object_class_find_property (gobject_class, "keep-alive"))
    g_object_set (downloader->priv->urisrc, "keep-alive", TRUE, NULL);
  if (g_object_class_find_property (gobject_class, "extra-headers")) {
    if (referer || refresh || !allow_cache) {
      GstStructure *extra_headers = gst_structure_new_empty ("headers");

      if (referer)
        gst_structure_set (extra_headers, "Referer", G_TYPE_STRING, referer,
            NULL);

      if (!allow_cache)
        gst_structure_set (extra_headers, "Cache-Control", G_TYPE_STRING,
            "no-cache", NULL);
      else if (refresh)
        gst_structure_set (extra_headers, "Cache-Control", G_TYPE_STRING,
            "max-age=0", NULL);

      g_object_set (downloader->priv->urisrc, "extra-headers", extra_headers,
          NULL);

      gst_structure_free (extra_headers);
    } else {
      g_object_set (downloader->priv->urisrc, "extra-headers", NULL, NULL);
    }
  }

  /* add a sync handler for the bus messages to detect errors in the download */
  gst_element_set_bus (GST_ELEMENT (downloader->priv->urisrc),
      downloader->priv->bus);
  gst_bus_set_sync_handler (downloader->priv->bus,
      gst_uri_downloader_bus_handler, downloader, NULL);

  pad = gst_element_get_static_pad (downloader->priv->urisrc, "src");
  if (!pad)
    return FALSE;
  gst_pad_link (pad, downloader->priv->pad);
  gst_object_unref (pad);
  return TRUE;
}
Exemplo n.º 26
0
/*!
 * \brief CvCapture_GStreamer::open Open the given file with gstreamer
 * \param type CvCapture type. One of CV_CAP_GSTREAMER_*
 * \param filename Filename to open in case of CV_CAP_GSTREAMER_FILE
 * \return boolean. Specifies if opening was succesful.
 *
 * In case of CV_CAP_GSTREAMER_V4L(2), a pipelin is constructed as follows:
 *    v4l2src ! autoconvert ! appsink
 *
 *
 * The 'filename' parameter is not limited to filesystem paths, and may be one of the following:
 *
 *  - a normal filesystem path:
 *        e.g. video.avi or /path/to/video.avi or C:\\video.avi
 *  - an uri:
 *        e.g. file:///path/to/video.avi or rtsp:///path/to/stream.asf
 *  - a gstreamer pipeline description:
 *        e.g. videotestsrc ! videoconvert ! appsink
 *        the appsink name should be either 'appsink0' (the default) or 'opencvsink'
 *
 *  When dealing with a file, CvCapture_GStreamer will not drop frames if the grabbing interval
 *  larger than the framerate period. (Unlike the uri or manual pipeline description, which assume
 *  a live source)
 *
 *  The pipeline will only be started whenever the first frame is grabbed. Setting pipeline properties
 *  is really slow if we need to restart the pipeline over and over again.
 *
 *  TODO: the 'type' parameter is imo unneeded. for v4l2, filename 'v4l2:///dev/video0' can be used.
 *  I expect this to be the same for CV_CAP_GSTREAMER_1394. Is anyone actually still using v4l (v1)?
 *
 */
bool CvCapture_GStreamer::open( int type, const char* filename )
{
    CV_FUNCNAME("cvCaptureFromCAM_GStreamer");

    __BEGIN__;

    gst_initializer::init();

    bool file = false;
    bool stream = false;
    bool manualpipeline = false;
    char *uri = NULL;
    uridecodebin = NULL;
    GstElementFactory * testfac;
    GstStateChangeReturn status;

    if (type == CV_CAP_GSTREAMER_V4L){
        testfac = gst_element_factory_find("v4lsrc");
        if (!testfac){
            return false;
        }
        g_object_unref(G_OBJECT(testfac));
        filename = "v4lsrc ! "COLOR_ELEM" ! appsink";
    }
    if (type == CV_CAP_GSTREAMER_V4L2){
        testfac = gst_element_factory_find("v4l2src");
        if (!testfac){
            return false;
        }
        g_object_unref(G_OBJECT(testfac));
        filename = "v4l2src ! "COLOR_ELEM" ! appsink";
    }


    // test if we have a valid uri. If so, open it with an uridecodebin
    // else, we might have a file or a manual pipeline.
    // if gstreamer cannot parse the manual pipeline, we assume we were given and
    // ordinary file path.
    if(!gst_uri_is_valid(filename))
    {
        uri = realpath(filename, NULL);
        stream = false;
        if(uri)
        {
            uri = g_filename_to_uri(uri, NULL, NULL);
            if(uri)
            {
                file = true;
            }
            else
            {
                CV_WARN("GStreamer: Error opening file\n");
                close();
                return false;
            }
        }
        else
        {
            GError *err = NULL;
            uridecodebin = gst_parse_launch(filename, &err);
            if(!uridecodebin)
            {
                fprintf(stderr, "GStreamer: Error opening bin: %s\n", err->message);
                return false;
            }
            stream = true;
            manualpipeline = true;
        }
    } else {
        stream = true;
        uri = g_strdup(filename);
    }

    bool element_from_uri = false;
    if(!uridecodebin)
    {
        // At this writing, the v4l2 element (and maybe others too) does not support caps renegotiation.
        // This means that we cannot use an uridecodebin when dealing with v4l2, since setting
        // capture properties will not work.
        // The solution (probably only until gstreamer 1.2) is to make an element from uri when dealing with v4l2.
        gchar * protocol = gst_uri_get_protocol(uri);
        if (!strcasecmp(protocol , "v4l2"))
        {
#if GST_VERSION_MAJOR == 0
            uridecodebin = gst_element_make_from_uri(GST_URI_SRC, uri, "src");
#else
            uridecodebin = gst_element_make_from_uri(GST_URI_SRC, uri, "src", NULL);
#endif
            element_from_uri = true;
        }else{
            uridecodebin = gst_element_factory_make("uridecodebin", NULL);
            g_object_set(G_OBJECT(uridecodebin), "uri", uri, NULL);
        }
        g_free(protocol);

        if(!uridecodebin) {
            //fprintf(stderr, "GStreamer: Error opening bin: %s\n", err->message);
            close();
            return false;
        }
    }

    if(manualpipeline)
    {
        GstIterator *it = NULL;
#if GST_VERSION_MAJOR == 0
        it = gst_bin_iterate_sinks(GST_BIN(uridecodebin));
        if(gst_iterator_next(it, (gpointer *)&sink) != GST_ITERATOR_OK) {
            CV_ERROR(CV_StsError, "GStreamer: cannot find appsink in manual pipeline\n");
            return false;
        }
#else
        it = gst_bin_iterate_sinks (GST_BIN(uridecodebin));

        gboolean done = FALSE;
        GstElement *element = NULL;
        gchar* name = NULL;
        GValue value = G_VALUE_INIT;

        while (!done) {
          switch (gst_iterator_next (it, &value)) {
            case GST_ITERATOR_OK:
              element = GST_ELEMENT (g_value_get_object (&value));
              name = gst_element_get_name(element);
              if (name){
                if(strstr(name, "opencvsink") != NULL || strstr(name, "appsink") != NULL) {
                  sink = GST_ELEMENT ( gst_object_ref (element) );
                  done = TRUE;
                }
                g_free(name);
              }
              g_value_unset (&value);

              break;
            case GST_ITERATOR_RESYNC:
              gst_iterator_resync (it);
              break;
            case GST_ITERATOR_ERROR:
            case GST_ITERATOR_DONE:
              done = TRUE;
              break;
          }
        }
        gst_iterator_free (it);


        if (!sink){
            CV_ERROR(CV_StsError, "GStreamer: cannot find appsink in manual pipeline\n");
            return false;
        }
#endif
        pipeline = uridecodebin;
    }
    else
    {
        pipeline = gst_pipeline_new(NULL);
        // videoconvert (in 0.10: ffmpegcolorspace, in 1.x autovideoconvert)
        //automatically selects the correct colorspace conversion based on caps.
        color = gst_element_factory_make(COLOR_ELEM, NULL);
        sink = gst_element_factory_make("appsink", NULL);

        gst_bin_add_many(GST_BIN(pipeline), uridecodebin, color, sink, NULL);

        if(element_from_uri) {
            if(!gst_element_link(uridecodebin, color)) {
                CV_ERROR(CV_StsError, "GStreamer: cannot link color -> sink\n");
                gst_object_unref(pipeline);
                pipeline = NULL;
                return false;
            }
        }else{
            g_signal_connect(uridecodebin, "pad-added", G_CALLBACK(newPad), color);
        }

        if(!gst_element_link(color, sink)) {
            CV_ERROR(CV_StsError, "GStreamer: cannot link color -> sink\n");
            gst_object_unref(pipeline);
            pipeline = NULL;
            return false;
        }
    }

    //TODO: is 1 single buffer really high enough?
    gst_app_sink_set_max_buffers (GST_APP_SINK(sink), 1);
    gst_app_sink_set_drop (GST_APP_SINK(sink), stream);
    //do not emit signals: all calls will be synchronous and blocking
    gst_app_sink_set_emit_signals (GST_APP_SINK(sink), 0);

#if GST_VERSION_MAJOR == 0
    caps = gst_caps_new_simple("video/x-raw-rgb",
                               "bpp",        G_TYPE_INT, 24,
                               "red_mask",   G_TYPE_INT, 0x0000FF,
                               "green_mask", G_TYPE_INT, 0x00FF00,
                               "blue_mask",  G_TYPE_INT, 0xFF0000,
                               NULL);
#else
    // support 1 and 3 channel 8 bit data, as well as bayer (also  1 channel, 8bit)
    caps = gst_caps_from_string("video/x-raw, format=(string){BGR, GRAY8}; video/x-bayer,format=(string){rggb,bggr,grbg,gbrg}");
#endif
    gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
    gst_caps_unref(caps);

    // For video files only: set pipeline to PAUSED state to get its duration
    if (file)
    {
        status = gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PAUSED);
        if (status == GST_STATE_CHANGE_ASYNC)
        {
            // wait for status update
            GstState st1;
            GstState st2;
            status = gst_element_get_state(pipeline, &st1, &st2, GST_CLOCK_TIME_NONE);
        }
        if (status == GST_STATE_CHANGE_FAILURE)
        {
            handleMessage(pipeline);
            gst_object_unref(pipeline);
            pipeline = NULL;
            CV_ERROR(CV_StsError, "GStreamer: unable to start pipeline\n");
            return false;
        }

        GstFormat format;

        format = GST_FORMAT_DEFAULT;
#if GST_VERSION_MAJOR == 0
        if(!gst_element_query_duration(sink, &format, &duration))
#else
        if(!gst_element_query_duration(sink, format, &duration))
#endif
        {
            handleMessage(pipeline);
            CV_WARN("GStreamer: unable to query duration of stream");
            duration = -1;
            return true;
        }
    }
    else
    {
        duration = -1;
    }

    __END__;

    return true;
}
Exemplo n.º 27
0
gboolean
gst_udp_parse_uri (const gchar * uristr, gchar ** host, guint16 * port)
{
  gchar *protocol, *location_start;
  gchar *location, *location_end;
  gchar *colptr;

  /* consider no protocol to be udp:// */
  protocol = gst_uri_get_protocol (uristr);
  if (!protocol)
    goto no_protocol;
  if (strcmp (protocol, "udp") != 0)
    goto wrong_protocol;
  g_free (protocol);

  location_start = gst_uri_get_location (uristr);
  if (!location_start)
    return FALSE;

  GST_DEBUG ("got location '%s'", location_start);

  /* VLC compatibility, strip everything before the @ sign. VLC uses that as the
   * remote address. */
  location = g_strstr_len (location_start, -1, "@");
  if (location == NULL)
    location = location_start;
  else
    location += 1;

  if (location[0] == '[') {
    GST_DEBUG ("parse IPV6 address '%s'", location);
    location_end = strchr (location, ']');
    if (location_end == NULL)
      goto wrong_address;

    *host = g_strndup (location + 1, location_end - location - 1);
    colptr = strrchr (location_end, ':');
  } else {
    GST_DEBUG ("parse IPV4 address '%s'", location);
    colptr = strrchr (location, ':');

    if (colptr != NULL) {
      *host = g_strndup (location, colptr - location);
    } else {
      *host = g_strdup (location);
    }
  }
  GST_DEBUG ("host set to '%s'", *host);

  if (colptr != NULL) {
    *port = g_ascii_strtoll (colptr + 1, NULL, 10);
  } else {
    *port = 0;
  }
  g_free (location_start);

  return TRUE;

  /* ERRORS */
no_protocol:
  {
    GST_ERROR ("error parsing uri %s: no protocol", uristr);
    return FALSE;
  }
wrong_protocol:
  {
    GST_ERROR ("error parsing uri %s: wrong protocol (%s != udp)", uristr,
        protocol);
    g_free (protocol);
    return FALSE;
  }
wrong_address:
  {
    GST_ERROR ("error parsing uri %s", uristr);
    g_free (location);
    return FALSE;
  }
}
static GstElement *
kms_recorder_endpoint_get_sink (KmsRecorderEndpoint * self)
{
  GObjectClass *sink_class;
  GstElement *sink = NULL;
  GParamSpec *pspec;
  GError *err = NULL;

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  if (KMS_URI_ENDPOINT (self)->uri == NULL)
    goto no_uri;

  if (!gst_uri_is_valid (KMS_URI_ENDPOINT (self)->uri))
    goto invalid_uri;

  sink = gst_element_make_from_uri (GST_URI_SINK, KMS_URI_ENDPOINT (self)->uri,
      NULL, &err);
  if (sink == NULL) {
    /* Some elements have no URI handling capabilities though they can */
    /* handle them. We try to find such element before failing to attend */
    /* this request */
    sink = kms_recorder_endpoint_get_sink_fallback (self);
    if (sink == NULL)
      goto no_sink;
    g_clear_error (&err);
  }

  /* Try to configure the sink element */
  sink_class = G_OBJECT_GET_CLASS (sink);

  pspec = g_object_class_find_property (sink_class, "location");
  if (pspec != NULL && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRING) {
    if (g_strcmp0 (GST_OBJECT_NAME (gst_element_get_factory (sink)),
            "filesink") == 0) {
      /* Work around for filesink elements */
      gchar *location = gst_uri_get_location (KMS_URI_ENDPOINT (self)->uri);

      GST_DEBUG_OBJECT (sink, "filesink location=%s", location);
      g_object_set (sink, "location", location, NULL);
      g_free (location);
    } else {
      GST_DEBUG_OBJECT (sink, "configuring location=%s",
          KMS_URI_ENDPOINT (self)->uri);
      g_object_set (sink, "location", KMS_URI_ENDPOINT (self)->uri, NULL);
    }
  }

  goto end;

no_uri:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
        ("No URI specified to record to."), GST_ERROR_SYSTEM);
    goto end;
  }
invalid_uri:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS, ("Invalid URI \"%s\".",
            KMS_URI_ENDPOINT (self)->uri), GST_ERROR_SYSTEM);
    g_clear_error (&err);
    goto end;
  }
no_sink:
  {
    /* whoops, could not create the sink element, dig a little deeper to
     * figure out what might be wrong. */
    if (err != NULL && err->code == GST_URI_ERROR_UNSUPPORTED_PROTOCOL) {
      gchar *prot;

      prot = gst_uri_get_protocol (KMS_URI_ENDPOINT (self)->uri);
      if (prot == NULL)
        goto invalid_uri;

      GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
          ("No URI handler implemented for \"%s\".", prot), GST_ERROR_SYSTEM);

      g_free (prot);
    } else {
      GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS, ("%s",
              (err) ? err->message : "URI was not accepted by any element"),
          GST_ERROR_SYSTEM);
    }

    g_clear_error (&err);
    goto end;
  }
end:
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
  return sink;
}