Exemple #1
0
static void
gst_fd_src_update_fd (GstFdSrc * src, guint64 size)
{
  struct stat stat_results;

  GST_DEBUG_OBJECT (src, "fdset %p, old_fd %d, new_fd %d", src->fdset, src->fd,
      src->new_fd);

  /* we need to always update the fdset since it may not have existed when
   * gst_fd_src_update_fd () was called earlier */
  if (src->fdset != NULL) {
    GstPollFD fd = GST_POLL_FD_INIT;

    if (src->fd >= 0) {
      fd.fd = src->fd;
      /* this will log a harmless warning, if it was never added */
      gst_poll_remove_fd (src->fdset, &fd);
    }

    fd.fd = src->new_fd;
    gst_poll_add_fd (src->fdset, &fd);
    gst_poll_fd_ctl_read (src->fdset, &fd, TRUE);
  }


  if (src->fd != src->new_fd) {
    GST_INFO_OBJECT (src, "Updating to fd %d", src->new_fd);

    src->fd = src->new_fd;

    GST_INFO_OBJECT (src, "Setting size to fd %" G_GUINT64_FORMAT, size);
    src->size = size;

    g_free (src->uri);
    src->uri = g_strdup_printf ("fd://%d", src->fd);

    if (fstat (src->fd, &stat_results) < 0)
      goto not_seekable;

    if (!S_ISREG (stat_results.st_mode))
      goto not_seekable;

    /* Try a seek of 0 bytes offset to check for seekability */
    if (lseek (src->fd, 0, SEEK_CUR) < 0)
      goto not_seekable;

    GST_INFO_OBJECT (src, "marking fd %d as seekable", src->fd);
    src->seekable_fd = TRUE;

    gst_base_src_set_dynamic_size (GST_BASE_SRC (src), TRUE);
  }
  return;

not_seekable:
  {
    GST_INFO_OBJECT (src, "marking fd %d as NOT seekable", src->fd);
    src->seekable_fd = FALSE;
    gst_base_src_set_dynamic_size (GST_BASE_SRC (src), FALSE);
  }
}
/* open the flite, necessary to go to READY state */
static gboolean
gst_flite_src_start (GstBaseSrc * basesrc)
{
  GstFliteSrc *src = GST_FLITE_SRC (basesrc);
  struct stat stat_results;

  if (src->filename == NULL || src->filename[0] == '\0')
    goto no_filename;

  GST_INFO_OBJECT (src, "opening file %s", src->filename);

  /* open the file */
  src->fd = gst_open (src->filename, O_RDONLY | O_BINARY, 0);

  if (src->fd < 0)
    goto open_failed;

  /* check if it is a regular file, otherwise bail out */
  if (fstat (src->fd, &stat_results) < 0)
    goto no_stat;

  if (S_ISDIR (stat_results.st_mode))
    goto was_directory;

  if (S_ISSOCK (stat_results.st_mode))
    goto was_socket;

  src->read_position = 0;

  /* record if it's a regular (hence seekable and lengthable) file */
  if (S_ISREG (stat_results.st_mode))
    src->is_regular = TRUE;

  /* We need to check if the underlying file is seekable. */
  {
    off_t res = lseek (src->fd, 0, SEEK_END);

    if (res < 0) {
      GST_LOG_OBJECT (src, "disabling seeking, lseek failed: %s",
          g_strerror (errno));
      src->seekable = FALSE;
    } else {
      res = lseek (src->fd, 0, SEEK_SET);

      if (res < 0) {
        /* We really don't like not being able to go back to 0 */
        src->seekable = FALSE;
        goto lseek_wonky;
      }

      src->seekable = TRUE;
    }
  }

  /* We can only really do seeking on regular files - for other file types, we
   * don't know their length, so seeking isn't useful/meaningful */
  src->seekable = src->seekable && src->is_regular;

  gst_base_src_set_dynamic_size (basesrc, src->seekable);

  return TRUE;

  /* ERROR */
no_filename:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
        (_("No file name specified for reading.")), (NULL));
    goto error_exit;
  }
open_failed:
  {
    switch (errno) {
      case ENOENT:
        GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
            ("No such file \"%s\"", src->filename));
        break;
      default:
        GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
            (_("Could not open file \"%s\" for reading."), src->filename),
            GST_ERROR_SYSTEM);
        break;
    }
    goto error_exit;
  }
no_stat:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("Could not get info on \"%s\"."), src->filename), (NULL));
    goto error_close;
  }
was_directory:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("\"%s\" is a directory."), src->filename), (NULL));
    goto error_close;
  }
was_socket:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (_("File \"%s\" is a socket."), src->filename), (NULL));
    goto error_close;
  }
lseek_wonky:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Could not seek back to zero after seek test in file \"%s\"",
            src->filename));
    goto error_close;
  }
error_close:
  close (src->fd);
error_exit:
  return FALSE;
}
static gboolean
gst_test_http_src_start (GstBaseSrc * basesrc)
{
  GstTestHTTPSrc *src;
  GstStructure *http_headers;

  src = GST_TEST_HTTP_SRC (basesrc);
  g_mutex_lock (&src->mutex);
  gst_test_http_src_reset_input (src);
  if (!src->uri) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (("No URL set.")),
        ("Missing location property"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (("Callbacks not registered.")), ("Callbacks not registered"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks->src_start) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (("src_start callback not defined.")),
        ("src_start callback not registered"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks->src_start (src, src->uri, &src->input,
          gst_test_http_src_callback_user_data)) {
    if (src->input.status_code == 0) {
      src->input.status_code = 404;
    }
  } else {
    if (src->input.status_code == 0) {
      src->input.status_code = 200;
    }
    src->position = 0;
    src->segment_end = src->input.size;
    gst_base_src_set_dynamic_size (basesrc, FALSE);
    basesrc->segment.duration = src->input.size;
    src->duration_changed = TRUE;
  }
  http_headers = gst_structure_new_empty ("http-headers");
  gst_structure_set (http_headers, "uri", G_TYPE_STRING, src->uri, NULL);
  if (!src->input.request_headers) {
    src->input.request_headers = gst_structure_new_empty ("request-headers");
  }
  if (!gst_structure_has_field_typed (src->input.request_headers,
          "User-Agent", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers,
        "User-Agent", G_TYPE_STRING,
        src->user_agent ? src->user_agent : DEFAULT_USER_AGENT, NULL);
  }
  if (!gst_structure_has_field_typed (src->input.request_headers,
          "Connection", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers,
        "Connection", G_TYPE_STRING,
        src->keep_alive ? "Keep-Alive" : "Close", NULL);
  }
  if (src->compress
      && !gst_structure_has_field_typed (src->input.request_headers,
          "Accept-Encoding", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers, "Accept-Encoding",
        G_TYPE_STRING, "compress, gzip", NULL);
  }
  gst_structure_set (http_headers, "request-headers", GST_TYPE_STRUCTURE,
      src->input.request_headers, NULL);
  if (!src->input.response_headers) {
    src->input.response_headers = gst_structure_new_empty ("response-headers");
  }
  if (!gst_structure_has_field_typed (src->input.response_headers,
          "Connection", G_TYPE_STRING)) {
    gst_structure_set (src->input.response_headers,
        "Connection", G_TYPE_STRING,
        src->keep_alive ? "keep-alive" : "close", NULL);
  }
  if (!gst_structure_has_field_typed (src->input.response_headers,
          "Date", G_TYPE_STRING)) {
    GDateTime *now;
    gchar *date_str;

    now = g_date_time_new_now_local ();
    fail_unless (now != NULL);
    date_str = g_date_time_format (now, "%a, %e %b %Y %T %Z");
    fail_unless (date_str != NULL);
    gst_structure_set (src->input.response_headers,
        "Date", G_TYPE_STRING, date_str, NULL);
    g_free (date_str);
    g_date_time_unref (now);
  }
  gst_structure_set (http_headers, "response-headers", GST_TYPE_STRUCTURE,
      src->input.response_headers, NULL);
  if (src->http_headers_event) {
    gst_event_unref (src->http_headers_event);
  }
  src->http_headers_event =
      gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, http_headers);
  g_mutex_unlock (&src->mutex);
  return TRUE;
}