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; }