static void gst_multi_file_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstMultiFileSrc *src = GST_MULTI_FILE_SRC (object); switch (prop_id) { case ARG_LOCATION: gst_multi_file_src_set_location (src, g_value_get_string (value)); break; case ARG_INDEX: src->index = g_value_get_int (value); break; case ARG_CAPS: { const GstCaps *caps = gst_value_get_caps (value); GstCaps *new_caps; if (caps == NULL) { new_caps = gst_caps_new_any (); } else { new_caps = gst_caps_copy (caps); } gst_caps_replace (&src->caps, new_caps); gst_pad_set_caps (GST_BASE_SRC_PAD (src), new_caps); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_multi_file_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstMultiFileSrc *src = GST_MULTI_FILE_SRC (object); switch (prop_id) { case ARG_LOCATION: g_value_set_string (value, src->filename); break; case ARG_INDEX: g_value_set_int (value, src->index); break; case ARG_START_INDEX: g_value_set_int (value, src->start_index); break; case ARG_STOP_INDEX: g_value_set_int (value, src->stop_index); break; case ARG_CAPS: gst_value_set_caps (value, src->caps); break; case ARG_LOOP: g_value_set_boolean (value, src->loop); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean gst_multi_file_src_query (GstBaseSrc * src, GstQuery * query) { gboolean res; GstMultiFileSrc *mfsrc; mfsrc = GST_MULTI_FILE_SRC (src); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gst_query_parse_position (query, &format, NULL); switch (format) { case GST_FORMAT_BUFFERS: case GST_FORMAT_DEFAULT: gst_query_set_position (query, GST_FORMAT_BUFFERS, mfsrc->index); res = TRUE; break; default: res = GST_BASE_SRC_CLASS (parent_class)->query (src, query); break; } break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (src, query); break; } return res; }
static void gst_multi_file_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstMultiFileSrc *src = GST_MULTI_FILE_SRC (object); switch (prop_id) { case PROP_LOCATION: gst_multi_file_src_set_location (src, g_value_get_string (value)); break; case PROP_INDEX: GST_OBJECT_LOCK (src); /* index was really meant to be read-only, but for backwards-compatibility * we set start_index to make it work as it used to */ if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_FLAG_STARTED)) src->start_index = g_value_get_int (value); else src->index = g_value_get_int (value); GST_OBJECT_UNLOCK (src); break; case PROP_START_INDEX: src->start_index = g_value_get_int (value); break; case PROP_STOP_INDEX: src->stop_index = g_value_get_int (value); break; case PROP_CAPS: { GstStructure *st = NULL; const GstCaps *caps = gst_value_get_caps (value); GstCaps *new_caps; if (caps == NULL) { new_caps = gst_caps_new_any (); } else { new_caps = gst_caps_copy (caps); } gst_caps_replace (&src->caps, new_caps); gst_pad_set_caps (GST_BASE_SRC_PAD (src), new_caps); if (new_caps && gst_caps_get_size (new_caps) == 1 && (st = gst_caps_get_structure (new_caps, 0)) && gst_structure_get_fraction (st, "framerate", &src->fps_n, &src->fps_d)) { GST_INFO_OBJECT (src, "Seting framerate to %d/%d", src->fps_n, src->fps_d); } else { src->fps_n = -1; src->fps_d = -1; } } break; case PROP_LOOP: src->loop = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean do_seek (GstBaseSrc * bsrc, GstSegment * segment) { gboolean reverse; GstClockTime position; GstMultiFileSrc *src; src = GST_MULTI_FILE_SRC (bsrc); segment->time = segment->start; position = segment->position; reverse = segment->rate < 0; if (reverse) { GST_FIXME_OBJECT (src, "Handle reverse playback"); return FALSE; } /* now move to the position indicated */ if (src->fps_n) { src->index = gst_util_uint64_scale (position, src->fps_n, src->fps_d * GST_SECOND); } else { src->index = 0; GST_WARNING_OBJECT (src, "No FPS set, can not seek"); return FALSE; } return TRUE; }
static gboolean is_seekable (GstBaseSrc * src) { GstMultiFileSrc *mfs = GST_MULTI_FILE_SRC (src); if (mfs->fps_n != -1) return TRUE; return FALSE; }
static void gst_multi_file_src_dispose (GObject * object) { GstMultiFileSrc *src = GST_MULTI_FILE_SRC (object); g_free (src->filename); src->filename = NULL; if (src->caps) gst_caps_unref (src->caps); G_OBJECT_CLASS (parent_class)->dispose (object); }
static GstCaps * gst_multi_file_src_getcaps (GstBaseSrc * src) { GstMultiFileSrc *multi_file_src = GST_MULTI_FILE_SRC (src); GST_DEBUG_OBJECT (src, "returning %" GST_PTR_FORMAT, multi_file_src->caps); if (multi_file_src->caps) { return gst_caps_ref (multi_file_src->caps); } else { return gst_caps_new_any (); } }
static GstCaps * gst_multi_file_src_getcaps (GstBaseSrc * src, GstCaps * filter) { GstMultiFileSrc *multi_file_src = GST_MULTI_FILE_SRC (src); GST_DEBUG_OBJECT (src, "returning %" GST_PTR_FORMAT, multi_file_src->caps); if (multi_file_src->caps) { if (filter) return gst_caps_intersect_full (filter, multi_file_src->caps, GST_CAPS_INTERSECT_FIRST); else return gst_caps_ref (multi_file_src->caps); } else { if (filter) return gst_caps_ref (filter); else return gst_caps_new_any (); } }
static GstFlowReturn gst_multi_file_src_create (GstPushSrc * src, GstBuffer ** buffer) { GstMultiFileSrc *multifilesrc; gsize size; gchar *data; gchar *filename; GstBuffer *buf; gboolean ret; GError *error = NULL; multifilesrc = GST_MULTI_FILE_SRC (src); filename = gst_multi_file_src_get_filename (multifilesrc); GST_DEBUG_OBJECT (multifilesrc, "reading from file \"%s\".", filename); ret = g_file_get_contents (filename, &data, &size, &error); if (!ret) { if (multifilesrc->successful_read) { /* If we've read at least one buffer successfully, not finding the * next file is EOS. */ g_free (filename); if (error != NULL) g_error_free (error); return GST_FLOW_UNEXPECTED; } else { goto handle_error; } } multifilesrc->successful_read = TRUE; multifilesrc->index++; buf = gst_buffer_new (); GST_BUFFER_DATA (buf) = (unsigned char *) data; GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf); GST_BUFFER_SIZE (buf) = size; GST_BUFFER_OFFSET (buf) = multifilesrc->offset; GST_BUFFER_OFFSET_END (buf) = multifilesrc->offset + size; multifilesrc->offset += size; gst_buffer_set_caps (buf, multifilesrc->caps); GST_DEBUG_OBJECT (multifilesrc, "read file \"%s\".", filename); g_free (filename); *buffer = buf; return GST_FLOW_OK; handle_error: { if (error != NULL) { GST_ELEMENT_ERROR (multifilesrc, RESOURCE, READ, ("Error while reading from file \"%s\".", filename), ("%s", error->message)); g_error_free (error); } else { GST_ELEMENT_ERROR (multifilesrc, RESOURCE, READ, ("Error while reading from file \"%s\".", filename), ("%s", g_strerror (errno))); } g_free (filename); return GST_FLOW_ERROR; } }
static GstFlowReturn gst_multi_file_src_create (GstPushSrc * src, GstBuffer ** buffer) { GstMultiFileSrc *multifilesrc; gsize size; gchar *data; gchar *filename; GstBuffer *buf; gboolean ret; GError *error = NULL; multifilesrc = GST_MULTI_FILE_SRC (src); if (multifilesrc->index < multifilesrc->start_index) { multifilesrc->index = multifilesrc->start_index; } filename = gst_multi_file_src_get_filename (multifilesrc); GST_DEBUG_OBJECT (multifilesrc, "reading from file \"%s\".", filename); ret = g_file_get_contents (filename, &data, &size, &error); if (!ret) { if (multifilesrc->successful_read) { /* If we've read at least one buffer successfully, not finding the * next file is EOS. */ g_free (filename); if (error != NULL) g_error_free (error); if (multifilesrc->loop) { error = NULL; multifilesrc->index = multifilesrc->start_index; filename = gst_multi_file_src_get_filename (multifilesrc); ret = g_file_get_contents (filename, &data, &size, &error); if (!ret) { g_free (filename); if (error != NULL) g_error_free (error); return GST_FLOW_EOS; } } else { return GST_FLOW_EOS; } } else { goto handle_error; } } multifilesrc->successful_read = TRUE; multifilesrc->index++; if (multifilesrc->stop_index != -1 && multifilesrc->index >= multifilesrc->stop_index) { multifilesrc->index = multifilesrc->start_index; } buf = gst_buffer_new (); gst_buffer_append_memory (buf, gst_memory_new_wrapped (0, data, size, 0, size, data, g_free)); GST_BUFFER_OFFSET (buf) = multifilesrc->offset; GST_BUFFER_OFFSET_END (buf) = multifilesrc->offset + size; multifilesrc->offset += size; GST_DEBUG_OBJECT (multifilesrc, "read file \"%s\".", filename); g_free (filename); *buffer = buf; return GST_FLOW_OK; handle_error: { if (error != NULL) { GST_ELEMENT_ERROR (multifilesrc, RESOURCE, READ, ("Error while reading from file \"%s\".", filename), ("%s", error->message)); g_error_free (error); } else { GST_ELEMENT_ERROR (multifilesrc, RESOURCE, READ, ("Error while reading from file \"%s\".", filename), ("%s", g_strerror (errno))); } g_free (filename); return GST_FLOW_ERROR; } }