static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
static gboolean gst_base_src_default_prepare_seek_segment (GstBaseSrc * src,
GstEvent * event, GstSegment * segment);
+static GstFlowReturn gst_base_src_default_create (GstBaseSrc * basesrc,
+ guint64 offset, guint size, GstBuffer ** buf);
static gboolean gst_base_src_set_flushing (GstBaseSrc * basesrc,
gboolean flushing, gboolean live_play, gboolean unlock, gboolean * playing);
gobject_class->set_property = gst_base_src_set_property;
gobject_class->get_property = gst_base_src_get_property;
-/* FIXME 0.11: blocksize property should be int, not ulong (min is >max here) */
g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
- g_param_spec_ulong ("blocksize", "Block size",
- "Size in bytes to read per buffer (-1 = default)", 0, G_MAXULONG,
+ g_param_spec_uint ("blocksize", "Block size",
+ "Size in bytes to read per buffer (-1 = default)", 0, G_MAXUINT,
DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
g_param_spec_int ("num-buffers", "num-buffers",
klass->query = GST_DEBUG_FUNCPTR (gst_base_src_default_query);
klass->prepare_seek_segment =
GST_DEBUG_FUNCPTR (gst_base_src_default_prepare_seek_segment);
+ klass->create = GST_DEBUG_FUNCPTR (gst_base_src_default_create);
/* Registering debug symbols for function pointers */
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_activate_push);
*
* Since: 0.10.22
*/
-/* FIXME 0.11: blocksize property should be int, not ulong */
void
-gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
+gst_base_src_set_blocksize (GstBaseSrc * src, guint blocksize)
{
g_return_if_fail (GST_IS_BASE_SRC (src));
*
* Since: 0.10.22
*/
-/* FIXME 0.11: blocksize property should be int, not ulong */
-gulong
+guint
gst_base_src_get_blocksize (GstBaseSrc * src)
{
- gulong res;
+ gint res;
g_return_val_if_fail (GST_IS_BASE_SRC (src), 0);
return result;
}
+static GstFlowReturn
+gst_base_src_default_create (GstBaseSrc * src, guint64 offset,
+ guint size, GstBuffer ** buffer)
+{
+ GstBaseSrcClass *bclass;
+ GstFlowReturn ret;
+ GstBuffer *buf;
+
+ bclass = GST_BASE_SRC_GET_CLASS (src);
+
+ if (G_UNLIKELY (!bclass->fill))
+ goto no_function;
+
+ buf = gst_buffer_new_and_alloc (size);
+ if (G_UNLIKELY (buf == NULL))
+ goto alloc_failed;
+
+ if (G_LIKELY (size > 0)) {
+ /* only call fill when there is a size */
+ ret = bclass->fill (src, offset, size, buf);
+
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
+ goto not_ok;
+ }
+
+ *buffer = buf;
+
+ return GST_FLOW_OK;
+
+ /* ERRORS */
+no_function:
+ {
+ GST_DEBUG_OBJECT (src, "no fill function");
+ return GST_FLOW_NOT_SUPPORTED;
+ }
+alloc_failed:
+ {
+ GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
+ return GST_FLOW_ERROR;
+ }
+not_ok:
+ {
+ GST_DEBUG_OBJECT (src, "fill returned %d (%s)", ret,
+ gst_flow_get_name (ret));
+ gst_buffer_unref (buf);
+ return ret;
+ }
+}
+
/* this code implements the seeking. It is a good example
* handling all cases.
*
switch (prop_id) {
case PROP_BLOCKSIZE:
- gst_base_src_set_blocksize (src, g_value_get_ulong (value));
+ gst_base_src_set_blocksize (src, g_value_get_uint (value));
break;
case PROP_NUM_BUFFERS:
src->num_buffers = g_value_get_int (value);
switch (prop_id) {
case PROP_BLOCKSIZE:
- g_value_set_ulong (value, gst_base_src_get_blocksize (src));
+ g_value_set_uint (value, gst_base_src_get_blocksize (src));
break;
case PROP_NUM_BUFFERS:
g_value_set_int (value, src->num_buffers);
no_function:
{
GST_DEBUG_OBJECT (src, "no create function");
- return GST_FLOW_ERROR;
+ return GST_FLOW_NOT_SUPPORTED;
}
unexpected_length:
{
GstFlowReturn ret;
gint64 position;
gboolean eos;
- gulong blocksize;
+ guint blocksize;
GList *pending_events = NULL, *tmp;
gboolean reconfigure;
} else
position = -1;
- GST_LOG_OBJECT (src, "next_ts %" GST_TIME_FORMAT " size %lu",
+ GST_LOG_OBJECT (src, "next_ts %" GST_TIME_FORMAT " size %u",
GST_TIME_ARGS (position), blocksize);
ret = gst_base_src_get_range (src, position, blocksize, &buf);
gboolean live_running;
/* MT-protected (with LOCK) */
- gint blocksize; /* size of buffers when operating push based */
+ guint blocksize; /* size of buffers when operating push based */
gboolean can_activate_push; /* some scheduling properties */
GstActivateMode pad_mode;
gboolean seekable; /* not used anymore */
* @get_caps: Called to get the caps to report
* @set_caps: Notify subclass of changed output caps
* @negotiate: Negotiated the caps with the peer.
+ * @fixate: Called during negotiation if caps need fixating. Implement instead of
+ * setting a fixate function on the source pad.
* @start: Start processing. Subclasses should open resources and prepare
* to produce data.
* @stop: Stop processing. Subclasses should use this to close resources.
* these times.
* @get_size: Return the total size of the resource, in the configured format.
* @is_seekable: Check if the source can seek
+ * @prepare_seek_segment: Prepare the GstSegment that will be passed to the
+ * do_seek vmethod for executing a seek request. Sub-classes should override
+ * this if they support seeking in formats other than the configured native
+ * format. By default, it tries to convert the seek arguments to the
+ * configured native format and prepare a segment in that format.
+ * Since: 0.10.13
+ * @do_seek: Perform seeking on the resource to the indicated segment.
* @unlock: Unlock any pending access to the resource. Subclasses should
* unblock any blocked function ASAP. In particular, any create() function in
* progress should be unblocked and should return GST_FLOW_WRONG_STATE. Any
* until the @unlock_stop<!-- -->() function has been called.
* @unlock_stop: Clear the previous unlock request. Subclasses should clear
* any state they set during unlock(), such as clearing command queues.
+ * @query: Handle a requested query.
* @event: Override this to implement custom event handling.
* @create: Ask the subclass to create a buffer with offset and size.
* When the subclass returns GST_FLOW_OK, it MUST return a buffer of the
* requested size unless fewer bytes are available because an EOS condition
* is near. No buffer should be returned when the return value is different
* from GST_FLOW_OK. A return value of GST_FLOW_UNEXPECTED signifies that the
- * end of stream is reached.
- * @do_seek: Perform seeking on the resource to the indicated segment.
- * @prepare_seek_segment: Prepare the GstSegment that will be passed to the
- * do_seek vmethod for executing a seek request. Sub-classes should override
- * this if they support seeking in formats other than the configured native
- * format. By default, it tries to convert the seek arguments to the
- * configured native format and prepare a segment in that format.
- * Since: 0.10.13
- * @query: Handle a requested query.
- * @fixate: Called during negotiation if caps need fixating. Implement instead of
- * setting a fixate function on the source pad.
+ * end of stream is reached. The default implementation will create a new
+ * buffer from the negotiated allocator and will call @fill.
+ * @fill: Ask the subclass to fill the buffer with data for offset and size. The
+ * passed buffer is guaranteed to hold the requested amount of bytes.
*
* Subclasses can override any of the available virtual methods or not, as
* needed. At the minimum, the @create method should be overridden to produce
/* notify subclasses of an event */
gboolean (*event) (GstBaseSrc *src, GstEvent *event);
- /* ask the subclass to create a buffer with offset and size */
+ /* ask the subclass to create a buffer with offset and size, the default
+ * implementation will use the negotiated allocator and call fill. */
GstFlowReturn (*create) (GstBaseSrc *src, guint64 offset, guint size,
GstBuffer **buf);
+ /* ask the subclass to fill the buffer with data from offset and size */
+ GstFlowReturn (*fill) (GstBaseSrc *src, guint64 offset, guint size,
+ GstBuffer *buf);
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE];
GstClockTime * min_latency,
GstClockTime * max_latency);
-void gst_base_src_set_blocksize (GstBaseSrc *src, gulong blocksize);
-gulong gst_base_src_get_blocksize (GstBaseSrc *src);
+void gst_base_src_set_blocksize (GstBaseSrc *src, guint blocksize);
+guint gst_base_src_get_blocksize (GstBaseSrc *src);
void gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean timestamp);
gboolean gst_base_src_get_do_timestamp (GstBaseSrc *src);
static gboolean gst_file_src_is_seekable (GstBaseSrc * src);
static gboolean gst_file_src_get_size (GstBaseSrc * src, guint64 * size);
-static GstFlowReturn gst_file_src_create (GstBaseSrc * src, guint64 offset,
- guint length, GstBuffer ** buffer);
+static GstFlowReturn gst_file_src_fill (GstBaseSrc * src, guint64 offset,
+ guint length, GstBuffer * buf);
static gboolean gst_file_src_query (GstBaseSrc * src, GstQuery * query);
static void gst_file_src_uri_handler_init (gpointer g_iface,
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_file_src_stop);
gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_file_src_is_seekable);
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_file_src_get_size);
- gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_file_src_create);
+ gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_file_src_fill);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_file_src_query);
if (sizeof (off_t) < 8) {
*
*/
static GstFlowReturn
-gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length,
- GstBuffer ** buffer)
+gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length,
+ GstBuffer * buf)
{
+ GstFileSrc *src;
int ret;
- GstBuffer *buf;
guint8 *data;
- gsize size;
+
+ src = GST_FILE_SRC_CAST (basesrc);
if (G_UNLIKELY (src->read_position != offset)) {
off_t res;
src->read_position = offset;
}
- buf = gst_buffer_new_and_alloc (length);
- if (G_UNLIKELY (buf == NULL && length > 0))
- goto alloc_failed;
+ data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
- /* No need to read anything if length is 0 */
- if (length > 0) {
- data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
+ GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x",
+ length, offset);
- GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x",
- length, offset);
- ret = read (src->fd, data, length);
- if (G_UNLIKELY (ret < 0))
- goto could_not_read;
+ ret = read (src->fd, data, length);
+ if (G_UNLIKELY (ret < 0))
+ goto could_not_read;
- /* seekable regular files should have given us what we expected */
- if (G_UNLIKELY ((guint) ret < length && src->seekable))
- goto unexpected_eos;
+ /* seekable regular files should have given us what we expected */
+ if (G_UNLIKELY ((guint) ret < length && src->seekable))
+ goto unexpected_eos;
- /* other files should eos if they read 0 and more was requested */
- if (G_UNLIKELY (ret == 0 && length > 0))
- goto eos;
+ /* other files should eos if they read 0 and more was requested */
+ if (G_UNLIKELY (ret == 0))
+ goto eos;
- length = ret;
+ length = ret;
- gst_buffer_unmap (buf, data, length);
+ gst_buffer_unmap (buf, data, length);
- GST_BUFFER_OFFSET (buf) = offset;
- GST_BUFFER_OFFSET_END (buf) = offset + length;
-
- src->read_position += length;
- }
+ GST_BUFFER_OFFSET (buf) = offset;
+ GST_BUFFER_OFFSET_END (buf) = offset + length;
- *buffer = buf;
+ src->read_position += length;
return GST_FLOW_OK;
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
return GST_FLOW_ERROR;
}
-alloc_failed:
- {
- GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", length);
- return GST_FLOW_ERROR;
- }
could_not_read:
{
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
gst_buffer_unmap (buf, data, 0);
- gst_buffer_unref (buf);
return GST_FLOW_ERROR;
}
unexpected_eos:
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
("unexpected end of file."));
gst_buffer_unmap (buf, data, 0);
- gst_buffer_unref (buf);
return GST_FLOW_ERROR;
}
eos:
{
GST_DEBUG ("non-regular file hits EOS");
gst_buffer_unmap (buf, data, 0);
- gst_buffer_unref (buf);
return GST_FLOW_UNEXPECTED;
}
}
-static GstFlowReturn
-gst_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
- GstBuffer ** buffer)
-{
- GstFileSrc *src;
- GstFlowReturn ret;
-
- src = GST_FILE_SRC_CAST (basesrc);
-
- ret = gst_file_src_create_read (src, offset, length, buffer);
-
- return ret;
-}
-
static gboolean
gst_file_src_query (GstBaseSrc * basesrc, GstQuery * query)
{