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; }
/** * 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; } }
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; }
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; }
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; }
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; } }
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; }
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; }
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; }
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; }
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); } }
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; }
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; } }
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); }
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; }
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; }
/** * 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; } }
/*! * \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; }
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; }
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; } }
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; }
/*! * \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; }
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; }