static void check_uri_for_uri (GstElement * e, const gchar * in_uri, const gchar * uri) { GstQuery *query; gchar *query_uri = NULL; gst_uri_handler_set_uri (GST_URI_HANDLER (e), in_uri, NULL); query = gst_query_new_uri (); fail_unless (gst_element_query (e, query)); gst_query_parse_uri (query, &query_uri); gst_query_unref (query); if (uri != NULL) { fail_unless_equals_string (query_uri, uri); } else { gchar *fn; fail_unless (gst_uri_is_valid (query_uri)); fn = g_filename_from_uri (query_uri, NULL, NULL); fail_unless (g_path_is_absolute (fn)); fail_unless (fn != NULL); g_free (fn); } g_free (query_uri); }
static void check_uri_for_location (GstElement * e, const gchar * location, const gchar * uri) { GstQuery *query; gchar *query_uri = NULL; g_object_set (e, "location", location, NULL); query = gst_query_new_uri (); fail_unless (gst_element_query (e, query)); gst_query_parse_uri (query, &query_uri); gst_query_unref (query); if (uri != NULL) { fail_unless_equals_string (query_uri, uri); } else { gchar *fn; fail_unless (gst_uri_is_valid (query_uri)); fn = g_filename_from_uri (query_uri, NULL, NULL); fail_unless (g_path_is_absolute (fn)); fail_unless (fn != NULL); g_free (fn); } g_free (query_uri); }
static gboolean gst_hls_demux_sink_event (GstPad * pad, GstEvent * event) { GstHLSDemux *demux = GST_HLS_DEMUX (gst_pad_get_parent (pad)); GstQuery *query; gboolean ret; gchar *uri; switch (event->type) { case GST_EVENT_EOS:{ gchar *playlist; if (demux->playlist == NULL) { GST_WARNING_OBJECT (demux, "Received EOS without a playlist."); break; } GST_DEBUG_OBJECT (demux, "Got EOS on the sink pad: main playlist fetched"); query = gst_query_new_uri (); ret = gst_pad_peer_query (demux->sinkpad, query); if (ret) { gst_query_parse_uri (query, &uri); gst_hls_demux_set_location (demux, uri); g_free (uri); } gst_query_unref (query); playlist = gst_hls_src_buf_to_utf8_playlist ((gchar *) GST_BUFFER_DATA (demux->playlist), GST_BUFFER_SIZE (demux->playlist)); gst_buffer_unref (demux->playlist); if (playlist == NULL) { GST_WARNING_OBJECT (demux, "Error validating first playlist."); } else if (!gst_m3u8_client_update (demux->client, playlist)) { /* In most cases, this will happen if we set a wrong url in the * source element and we have received the 404 HTML response instead of * the playlist */ GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid playlist."), NULL); return FALSE; } if (!ret && gst_m3u8_client_is_live (demux->client)) { GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Failed querying the playlist uri, " "required for live sources."), NULL); return FALSE; } gst_task_start (demux->task); gst_event_unref (event); return TRUE; } default: break; } return gst_pad_event_default (pad, event); }
/* generate queries to adaptive demux */ static gboolean testQueryCheckDataReceived (GstAdaptiveDemuxTestEngine * engine, GstAdaptiveDemuxTestOutputStream * stream, GstBuffer * buffer, gpointer user_data) { GList *pads; GstPad *pad; GstQuery *query; gboolean ret; gint64 duration; gboolean seekable; gint64 segment_start; gint64 segment_end; gchar *uri; gchar *redirect_uri; gboolean redirect_permanent; pads = GST_ELEMENT_PADS (stream->appsink); /* AppSink should have only 1 pad */ fail_unless (pads != NULL); fail_unless (g_list_length (pads) == 1); pad = GST_PAD (pads->data); query = gst_query_new_duration (GST_FORMAT_TIME); ret = gst_pad_peer_query (pad, query); fail_unless (ret == TRUE); gst_query_parse_duration (query, NULL, &duration); fail_unless (duration == 135743 * GST_MSECOND); gst_query_unref (query); query = gst_query_new_seeking (GST_FORMAT_TIME); ret = gst_pad_peer_query (pad, query); fail_unless (ret == TRUE); gst_query_parse_seeking (query, NULL, &seekable, &segment_start, &segment_end); fail_unless (seekable == TRUE); fail_unless (segment_start == 0); fail_unless (segment_end == duration); gst_query_unref (query); query = gst_query_new_uri (); ret = gst_pad_peer_query (pad, query); fail_unless (ret == TRUE); gst_query_parse_uri (query, &uri); gst_query_parse_uri_redirection (query, &redirect_uri); gst_query_parse_uri_redirection_permanent (query, &redirect_permanent); fail_unless (strcmp (uri, "http://unit.test/test.mpd") == 0); /* adaptive demux does not reply with redirect information */ fail_unless (redirect_uri == NULL); fail_unless (redirect_permanent == FALSE); g_free (uri); g_free (redirect_uri); gst_query_unref (query); return gst_adaptive_demux_test_check_received_data (engine, stream, buffer, user_data); }
static gchar * gst_type_find_get_extension (GstTypeFindElement * typefind, GstPad * pad) { GstQuery *query; gchar *uri, *result; size_t len; gint find; query = gst_query_new_uri (); /* try getting the caps with an uri query and from the extension */ if (!gst_pad_peer_query (pad, query)) goto peer_query_failed; gst_query_parse_uri (query, &uri); if (uri == NULL) goto no_uri; GST_DEBUG_OBJECT (typefind, "finding extension of %s", uri); /* find the extension on the uri, this is everything after a '.' */ len = strlen (uri); find = len - 1; while (find >= 0) { if (uri[find] == '.') break; find--; } if (find < 0) goto no_extension; result = g_strdup (&uri[find + 1]); GST_DEBUG_OBJECT (typefind, "found extension %s", result); gst_query_unref (query); g_free (uri); return result; /* ERRORS */ peer_query_failed: { GST_WARNING_OBJECT (typefind, "failed to query peer uri"); gst_query_unref (query); return NULL; } no_uri: { GST_WARNING_OBJECT (typefind, "could not parse the peer uri"); gst_query_unref (query); return NULL; } no_extension: { GST_WARNING_OBJECT (typefind, "could not find uri extension in %s", uri); gst_query_unref (query); g_free (uri); return NULL; } }
/** * 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; } }
static GstCaps * gst_type_find_guess_by_extension (GstTypeFindElement * typefind, GstPad * pad, GstTypeFindProbability * probability) { GstQuery *query; gchar *uri; size_t len; gint find; GstCaps *caps; query = gst_query_new_uri (); /* try getting the caps with an uri query and from the extension */ if (!gst_pad_peer_query (pad, query)) goto peer_query_failed; gst_query_parse_uri (query, &uri); if (uri == NULL) goto no_uri; GST_DEBUG_OBJECT (typefind, "finding extension of %s", uri); /* find the extension on the uri, this is everything after a '.' */ len = strlen (uri); find = len - 1; while (find >= 0) { if (uri[find] == '.') break; find--; } if (find < 0) goto no_extension; GST_DEBUG_OBJECT (typefind, "found extension %s", &uri[find + 1]); caps = gst_type_find_helper_for_extension (GST_OBJECT_CAST (typefind), &uri[find + 1]); if (caps) *probability = GST_TYPE_FIND_MAXIMUM; gst_query_unref (query); return caps; /* ERRORS */ peer_query_failed: { GST_WARNING_OBJECT (typefind, "failed to query peer uri"); gst_query_unref (query); return NULL; } no_uri: { GST_WARNING_OBJECT (typefind, "could not parse the peer uri"); gst_query_unref (query); return NULL; } no_extension: { GST_WARNING_OBJECT (typefind, "could not find uri extension in %s", uri); gst_query_unref (query); return NULL; } }
QUrl UriQuery::uri() const { gchar *uri; gst_query_parse_uri(object<GstQuery>(), &uri); return QUrl::fromPercentEncoding(uri); }
static gboolean gst_ss_demux_sink_event (GstPad * pad, GstEvent * event) { GstSSDemux *demux = GST_SS_DEMUX (gst_pad_get_parent (pad)); GstQuery *query; gboolean ret; gchar *uri; switch (event->type) { case GST_EVENT_EOS: { int i = 0; if (demux->manifest == NULL) { GST_WARNING_OBJECT (demux, "Received EOS without a manifest."); break; } GST_DEBUG_OBJECT (demux, "Got EOS on the sink pad: mainifest file fetched"); query = gst_query_new_uri (); ret = gst_pad_peer_query (demux->sinkpad, query); if (ret) { gst_query_parse_uri (query, &uri); demux->parser = gst_ssm_parse_new (uri); g_free (uri); } else { GST_ERROR_OBJECT (demux, "failed to query URI from upstream"); return FALSE; } gst_query_unref (query); GST_LOG_OBJECT (demux, "data = %p & size = %d", GST_BUFFER_DATA(demux->manifest), GST_BUFFER_SIZE(demux->manifest)); if (!gst_ssm_parse_manifest (demux->parser, (char *)GST_BUFFER_DATA(demux->manifest), GST_BUFFER_SIZE(demux->manifest))) { /* In most cases, this will happen if we set a wrong url in the * source element and we have received the 404 HTML response instead of * the playlist */ GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid playlist."), (NULL)); return FALSE; } for( i = 0; i < SS_STREAM_NUM; i++) { if (gst_ssm_parse_check_stream (demux->parser, i)) { GstSSDemuxStream *stream = g_new0 (GstSSDemuxStream, 1); // Add pad emission of the stream gst_ss_demux_stream_init (demux, stream, i); g_static_rec_mutex_init (&stream->stream_lock); stream->stream_task = gst_task_create ((GstTaskFunction) gst_ss_demux_stream_loop, demux); gst_task_set_lock (stream->stream_task, &stream->stream_lock); demux->streams[i] = stream; g_print ("Starting stream - %d task loop...\n", i); gst_task_start (stream->stream_task); } } gst_event_unref (event); return TRUE; } case GST_EVENT_NEWSEGMENT: /* Swallow newsegments, we'll push our own */ gst_event_unref (event); return TRUE; default: break; } return gst_pad_event_default (pad, event); }