Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
/* 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;
  }
}
Beispiel #8
0
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);
}