GstFragment * gst_uri_downloader_fetch_uri (GstUriDownloader * downloader, const gchar * uri) { GstStateChangeReturn ret; GstFragment *download = NULL; g_mutex_lock (&downloader->priv->lock); if (downloader->priv->cancelled) { goto quit; } if (!gst_uri_downloader_set_uri (downloader, uri)) { goto quit; } downloader->priv->download = gst_fragment_new (); gst_bus_set_flushing (downloader->priv->bus, FALSE); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; 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); g_cond_wait (&downloader->priv->cond, &downloader->priv->lock); if (downloader->priv->cancelled) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } GST_OBJECT_LOCK (downloader); download = downloader->priv->download; downloader->priv->download = NULL; GST_OBJECT_UNLOCK (downloader); if (download != NULL) GST_INFO_OBJECT (downloader, "URI fetched successfully"); else GST_INFO_OBJECT (downloader, "Error fetching URI"); quit: { gst_uri_downloader_stop (downloader); g_mutex_unlock (&downloader->priv->lock); return download; } }
/** * gst_uri_downloader_fetch_uri_with_range: * @downloader: the #GstUriDownloader * @uri: the uri * @range_start: the starting byte index * @range_end: the final byte index, use -1 for unspecified * * Returns the downloaded #GstFragment */ GstFragment * gst_uri_downloader_fetch_uri_with_range (GstUriDownloader * downloader, const gchar * uri, const gchar * referer, gboolean compress, gboolean refresh, gboolean allow_cache, gint64 range_start, gint64 range_end, GError ** err) { GstStateChangeReturn ret; GstFragment *download = NULL; GST_DEBUG_OBJECT (downloader, "Fetching URI %s", uri); g_mutex_lock (&downloader->priv->download_lock); downloader->priv->err = NULL; downloader->priv->got_buffer = FALSE; GST_OBJECT_LOCK (downloader); if (downloader->priv->cancelled) { GST_DEBUG_OBJECT (downloader, "Cancelled, aborting fetch"); goto quit; } if (!gst_uri_downloader_set_uri (downloader, uri, referer, compress, refresh, allow_cache)) { GST_WARNING_OBJECT (downloader, "Failed to set URI"); goto quit; } gst_bus_set_flushing (downloader->priv->bus, FALSE); if (downloader->priv->download) g_object_unref (downloader->priv->download); downloader->priv->download = gst_fragment_new (); downloader->priv->download->range_start = range_start; downloader->priv->download->range_end = range_end; GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_READY); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE || downloader->priv->download == NULL) { GST_WARNING_OBJECT (downloader, "Failed to set src to READY"); goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } if (range_start < 0 && range_end < 0) { if (!gst_uri_downloader_set_method (downloader, "HEAD")) { GST_WARNING_OBJECT (downloader, "Failed to set HTTP method"); goto quit; } } else { if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) { GST_WARNING_OBJECT (downloader, "Failed to set range"); goto quit; } } GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } /* wait until: * - the download succeed (EOS in the src pad) * - the download failed (Error message on the fetcher bus) * - the download was canceled */ GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI %s", uri); while (!downloader->priv->cancelled && !downloader->priv->download->completed) g_cond_wait (&downloader->priv->cond, GST_OBJECT_GET_LOCK (downloader)); if (downloader->priv->cancelled) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } download = downloader->priv->download; downloader->priv->download = NULL; if (!downloader->priv->got_buffer) { if (download->range_start < 0 && download->range_end < 0) { /* HEAD request, so we don't expect a response */ } else { g_object_unref (download); download = NULL; GST_ERROR_OBJECT (downloader, "Didn't retrieve a buffer before EOS"); } } if (download != NULL) GST_INFO_OBJECT (downloader, "URI fetched successfully"); else GST_INFO_OBJECT (downloader, "Error fetching URI"); quit: { if (downloader->priv->urisrc) { GstPad *pad; GstElement *urisrc; urisrc = downloader->priv->urisrc; GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (urisrc)); /* remove the bus' sync handler */ gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL); gst_bus_set_flushing (downloader->priv->bus, TRUE); /* set the element state to NULL */ GST_OBJECT_UNLOCK (downloader); if (download == NULL) { gst_element_set_state (urisrc, GST_STATE_NULL); } else { GstQuery *query; /* Download successfull, let's query the URI */ query = gst_query_new_uri (); if (gst_element_query (urisrc, query)) { gst_query_parse_uri (query, &download->uri); gst_query_parse_uri_redirection (query, &download->redirect_uri); gst_query_parse_uri_redirection_permanent (query, &download->redirect_permanent); } gst_query_unref (query); gst_element_set_state (urisrc, GST_STATE_READY); } GST_OBJECT_LOCK (downloader); gst_element_set_bus (urisrc, NULL); /* unlink the source element from the internal pad */ pad = gst_pad_get_peer (downloader->priv->pad); if (pad) { gst_pad_unlink (pad, downloader->priv->pad); gst_object_unref (pad); } } GST_OBJECT_UNLOCK (downloader); if (download == NULL) { if (!downloader->priv->err) { g_set_error (err, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ, "Failed to download '%s'", uri); } else { g_propagate_error (err, downloader->priv->err); downloader->priv->err = NULL; } } downloader->priv->cancelled = FALSE; g_mutex_unlock (&downloader->priv->download_lock); return download; } }
/** * gst_uri_downloader_fetch_uri_with_range: * @downloader: the #GstUriDownloader * @uri: the uri * @range_start: the starting byte index * @range_end: the final byte index, use -1 for unspecified * * Returns the downloaded #GstFragment */ GstFragment * gst_uri_downloader_fetch_uri_with_range (GstUriDownloader * downloader, const gchar * uri, gint64 range_start, gint64 range_end) { GstStateChangeReturn ret; GstFragment *download = NULL; GST_DEBUG_OBJECT (downloader, "Fetching URI %s", uri); g_mutex_lock (&downloader->priv->download_lock); GST_OBJECT_LOCK (downloader); if (downloader->priv->cancelled) { GST_DEBUG_OBJECT (downloader, "Cancelled, aborting fetch"); goto quit; } if (!gst_uri_downloader_set_uri (downloader, uri)) { GST_WARNING_OBJECT (downloader, "Failed to set URI"); goto quit; } gst_bus_set_flushing (downloader->priv->bus, FALSE); downloader->priv->download = gst_fragment_new (); GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_READY); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE || downloader->priv->download == NULL) { GST_WARNING_OBJECT (downloader, "Failed to set src to READY"); goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) { GST_WARNING_OBJECT (downloader, "Failed to set range"); goto quit; } GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } /* wait until: * - the download succeed (EOS in the src pad) * - the download failed (Error message on the fetcher bus) * - the download was canceled */ GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI %s", uri); while (!downloader->priv->cancelled && !downloader->priv->download->completed) g_cond_wait (&downloader->priv->cond, GST_OBJECT_GET_LOCK (downloader)); if (downloader->priv->cancelled) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } download = downloader->priv->download; downloader->priv->download = NULL; if (download != NULL) GST_INFO_OBJECT (downloader, "URI fetched successfully"); else GST_INFO_OBJECT (downloader, "Error fetching URI"); quit: { if (downloader->priv->urisrc) { GstPad *pad; GstElement *urisrc; GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (downloader->priv->urisrc)); /* remove the bus' sync handler */ gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL); /* unlink the source element from the internal pad */ pad = gst_pad_get_peer (downloader->priv->pad); if (pad) { gst_pad_unlink (pad, downloader->priv->pad); gst_object_unref (pad); } urisrc = downloader->priv->urisrc; downloader->priv->urisrc = NULL; GST_OBJECT_UNLOCK (downloader); GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (urisrc)); /* set the element state to NULL */ gst_bus_set_flushing (downloader->priv->bus, TRUE); gst_element_set_state (urisrc, GST_STATE_NULL); gst_element_get_state (urisrc, NULL, NULL, GST_CLOCK_TIME_NONE); gst_element_set_bus (urisrc, NULL); gst_object_unref (urisrc); } else { GST_OBJECT_UNLOCK (downloader); } g_mutex_unlock (&downloader->priv->download_lock); return download; } }