mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-02 21:48:55 +00:00
basesrc: add fill vmethod to basesrc
Add a new fill virtual method to basesrc. The purpose of this method is to fill a provided buffer with data. Add a default implementation of the create method that allocates a buffer and calls the fill method on it. This would allow the base class to implement bufferpool and allocator negotiation on behalf of the subclasses. Fix the blocksize property. Make filesrc use the new fill method.
This commit is contained in:
parent
2d28891528
commit
c35e0de65e
3 changed files with 109 additions and 82 deletions
|
@ -296,6 +296,8 @@ static gboolean gst_base_src_default_do_seek (GstBaseSrc * src,
|
||||||
static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
|
static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
|
||||||
static gboolean gst_base_src_default_prepare_seek_segment (GstBaseSrc * src,
|
static gboolean gst_base_src_default_prepare_seek_segment (GstBaseSrc * src,
|
||||||
GstEvent * event, GstSegment * segment);
|
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,
|
static gboolean gst_base_src_set_flushing (GstBaseSrc * basesrc,
|
||||||
gboolean flushing, gboolean live_play, gboolean unlock, gboolean * playing);
|
gboolean flushing, gboolean live_play, gboolean unlock, gboolean * playing);
|
||||||
|
@ -334,10 +336,9 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
|
||||||
gobject_class->set_property = gst_base_src_set_property;
|
gobject_class->set_property = gst_base_src_set_property;
|
||||||
gobject_class->get_property = gst_base_src_get_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_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
|
||||||
g_param_spec_ulong ("blocksize", "Block size",
|
g_param_spec_uint ("blocksize", "Block size",
|
||||||
"Size in bytes to read per buffer (-1 = default)", 0, G_MAXULONG,
|
"Size in bytes to read per buffer (-1 = default)", 0, G_MAXUINT,
|
||||||
DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
|
g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
|
||||||
g_param_spec_int ("num-buffers", "num-buffers",
|
g_param_spec_int ("num-buffers", "num-buffers",
|
||||||
|
@ -365,6 +366,7 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
|
||||||
klass->query = GST_DEBUG_FUNCPTR (gst_base_src_default_query);
|
klass->query = GST_DEBUG_FUNCPTR (gst_base_src_default_query);
|
||||||
klass->prepare_seek_segment =
|
klass->prepare_seek_segment =
|
||||||
GST_DEBUG_FUNCPTR (gst_base_src_default_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 */
|
/* Registering debug symbols for function pointers */
|
||||||
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_activate_push);
|
GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_activate_push);
|
||||||
|
@ -643,9 +645,8 @@ gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
|
||||||
*
|
*
|
||||||
* Since: 0.10.22
|
* Since: 0.10.22
|
||||||
*/
|
*/
|
||||||
/* FIXME 0.11: blocksize property should be int, not ulong */
|
|
||||||
void
|
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));
|
g_return_if_fail (GST_IS_BASE_SRC (src));
|
||||||
|
|
||||||
|
@ -664,11 +665,10 @@ gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
|
||||||
*
|
*
|
||||||
* Since: 0.10.22
|
* Since: 0.10.22
|
||||||
*/
|
*/
|
||||||
/* FIXME 0.11: blocksize property should be int, not ulong */
|
guint
|
||||||
gulong
|
|
||||||
gst_base_src_get_blocksize (GstBaseSrc * src)
|
gst_base_src_get_blocksize (GstBaseSrc * src)
|
||||||
{
|
{
|
||||||
gulong res;
|
gint res;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_BASE_SRC (src), 0);
|
g_return_val_if_fail (GST_IS_BASE_SRC (src), 0);
|
||||||
|
|
||||||
|
@ -1246,6 +1246,55 @@ gst_base_src_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
|
||||||
return result;
|
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
|
/* this code implements the seeking. It is a good example
|
||||||
* handling all cases.
|
* handling all cases.
|
||||||
*
|
*
|
||||||
|
@ -1770,7 +1819,7 @@ gst_base_src_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_BLOCKSIZE:
|
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;
|
break;
|
||||||
case PROP_NUM_BUFFERS:
|
case PROP_NUM_BUFFERS:
|
||||||
src->num_buffers = g_value_get_int (value);
|
src->num_buffers = g_value_get_int (value);
|
||||||
|
@ -1797,7 +1846,7 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_BLOCKSIZE:
|
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;
|
break;
|
||||||
case PROP_NUM_BUFFERS:
|
case PROP_NUM_BUFFERS:
|
||||||
g_value_set_int (value, src->num_buffers);
|
g_value_set_int (value, src->num_buffers);
|
||||||
|
@ -2211,7 +2260,7 @@ not_started:
|
||||||
no_function:
|
no_function:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "no create function");
|
GST_DEBUG_OBJECT (src, "no create function");
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
unexpected_length:
|
unexpected_length:
|
||||||
{
|
{
|
||||||
|
@ -2290,7 +2339,7 @@ gst_base_src_loop (GstPad * pad)
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint64 position;
|
gint64 position;
|
||||||
gboolean eos;
|
gboolean eos;
|
||||||
gulong blocksize;
|
guint blocksize;
|
||||||
GList *pending_events = NULL, *tmp;
|
GList *pending_events = NULL, *tmp;
|
||||||
gboolean reconfigure;
|
gboolean reconfigure;
|
||||||
|
|
||||||
|
@ -2333,7 +2382,7 @@ gst_base_src_loop (GstPad * pad)
|
||||||
} else
|
} else
|
||||||
position = -1;
|
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);
|
GST_TIME_ARGS (position), blocksize);
|
||||||
|
|
||||||
ret = gst_base_src_get_range (src, position, blocksize, &buf);
|
ret = gst_base_src_get_range (src, position, blocksize, &buf);
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct _GstBaseSrc {
|
||||||
gboolean live_running;
|
gboolean live_running;
|
||||||
|
|
||||||
/* MT-protected (with LOCK) */
|
/* 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 */
|
gboolean can_activate_push; /* some scheduling properties */
|
||||||
GstActivateMode pad_mode;
|
GstActivateMode pad_mode;
|
||||||
gboolean seekable; /* not used anymore */
|
gboolean seekable; /* not used anymore */
|
||||||
|
@ -117,6 +117,8 @@ struct _GstBaseSrc {
|
||||||
* @get_caps: Called to get the caps to report
|
* @get_caps: Called to get the caps to report
|
||||||
* @set_caps: Notify subclass of changed output caps
|
* @set_caps: Notify subclass of changed output caps
|
||||||
* @negotiate: Negotiated the caps with the peer.
|
* @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
|
* @start: Start processing. Subclasses should open resources and prepare
|
||||||
* to produce data.
|
* to produce data.
|
||||||
* @stop: Stop processing. Subclasses should use this to close resources.
|
* @stop: Stop processing. Subclasses should use this to close resources.
|
||||||
|
@ -125,6 +127,13 @@ struct _GstBaseSrc {
|
||||||
* these times.
|
* these times.
|
||||||
* @get_size: Return the total size of the resource, in the configured format.
|
* @get_size: Return the total size of the resource, in the configured format.
|
||||||
* @is_seekable: Check if the source can seek
|
* @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
|
* @unlock: Unlock any pending access to the resource. Subclasses should
|
||||||
* unblock any blocked function ASAP. In particular, any create() function in
|
* unblock any blocked function ASAP. In particular, any create() function in
|
||||||
* progress should be unblocked and should return GST_FLOW_WRONG_STATE. Any
|
* progress should be unblocked and should return GST_FLOW_WRONG_STATE. Any
|
||||||
|
@ -132,23 +141,17 @@ struct _GstBaseSrc {
|
||||||
* until the @unlock_stop<!-- -->() function has been called.
|
* until the @unlock_stop<!-- -->() function has been called.
|
||||||
* @unlock_stop: Clear the previous unlock request. Subclasses should clear
|
* @unlock_stop: Clear the previous unlock request. Subclasses should clear
|
||||||
* any state they set during unlock(), such as clearing command queues.
|
* any state they set during unlock(), such as clearing command queues.
|
||||||
|
* @query: Handle a requested query.
|
||||||
* @event: Override this to implement custom event handling.
|
* @event: Override this to implement custom event handling.
|
||||||
* @create: Ask the subclass to create a buffer with offset and size.
|
* @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
|
* 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
|
* requested size unless fewer bytes are available because an EOS condition
|
||||||
* is near. No buffer should be returned when the return value is different
|
* 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
|
* from GST_FLOW_OK. A return value of GST_FLOW_UNEXPECTED signifies that the
|
||||||
* end of stream is reached.
|
* end of stream is reached. The default implementation will create a new
|
||||||
* @do_seek: Perform seeking on the resource to the indicated segment.
|
* buffer from the negotiated allocator and will call @fill.
|
||||||
* @prepare_seek_segment: Prepare the GstSegment that will be passed to the
|
* @fill: Ask the subclass to fill the buffer with data for offset and size. The
|
||||||
* do_seek vmethod for executing a seek request. Sub-classes should override
|
* passed buffer is guaranteed to hold the requested amount of bytes.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* Subclasses can override any of the available virtual methods or not, as
|
* Subclasses can override any of the available virtual methods or not, as
|
||||||
* needed. At the minimum, the @create method should be overridden to produce
|
* needed. At the minimum, the @create method should be overridden to produce
|
||||||
|
@ -204,9 +207,13 @@ struct _GstBaseSrcClass {
|
||||||
/* notify subclasses of an event */
|
/* notify subclasses of an event */
|
||||||
gboolean (*event) (GstBaseSrc *src, GstEvent *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,
|
GstFlowReturn (*create) (GstBaseSrc *src, guint64 offset, guint size,
|
||||||
GstBuffer **buf);
|
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 >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||||
|
@ -227,8 +234,8 @@ gboolean gst_base_src_query_latency (GstBaseSrc *src, gboolean * live,
|
||||||
GstClockTime * min_latency,
|
GstClockTime * min_latency,
|
||||||
GstClockTime * max_latency);
|
GstClockTime * max_latency);
|
||||||
|
|
||||||
void gst_base_src_set_blocksize (GstBaseSrc *src, gulong blocksize);
|
void gst_base_src_set_blocksize (GstBaseSrc *src, guint blocksize);
|
||||||
gulong gst_base_src_get_blocksize (GstBaseSrc *src);
|
guint gst_base_src_get_blocksize (GstBaseSrc *src);
|
||||||
|
|
||||||
void gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean timestamp);
|
void gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean timestamp);
|
||||||
gboolean gst_base_src_get_do_timestamp (GstBaseSrc *src);
|
gboolean gst_base_src_get_do_timestamp (GstBaseSrc *src);
|
||||||
|
|
|
@ -146,8 +146,8 @@ static gboolean gst_file_src_stop (GstBaseSrc * basesrc);
|
||||||
|
|
||||||
static gboolean gst_file_src_is_seekable (GstBaseSrc * src);
|
static gboolean gst_file_src_is_seekable (GstBaseSrc * src);
|
||||||
static gboolean gst_file_src_get_size (GstBaseSrc * src, guint64 * size);
|
static gboolean gst_file_src_get_size (GstBaseSrc * src, guint64 * size);
|
||||||
static GstFlowReturn gst_file_src_create (GstBaseSrc * src, guint64 offset,
|
static GstFlowReturn gst_file_src_fill (GstBaseSrc * src, guint64 offset,
|
||||||
guint length, GstBuffer ** buffer);
|
guint length, GstBuffer * buf);
|
||||||
static gboolean gst_file_src_query (GstBaseSrc * src, GstQuery * query);
|
static gboolean gst_file_src_query (GstBaseSrc * src, GstQuery * query);
|
||||||
|
|
||||||
static void gst_file_src_uri_handler_init (gpointer g_iface,
|
static void gst_file_src_uri_handler_init (gpointer g_iface,
|
||||||
|
@ -197,7 +197,7 @@ gst_file_src_class_init (GstFileSrcClass * klass)
|
||||||
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_file_src_stop);
|
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_file_src_stop);
|
||||||
gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_file_src_is_seekable);
|
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->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);
|
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_file_src_query);
|
||||||
|
|
||||||
if (sizeof (off_t) < 8) {
|
if (sizeof (off_t) < 8) {
|
||||||
|
@ -325,13 +325,14 @@ gst_file_src_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length,
|
gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length,
|
||||||
GstBuffer ** buffer)
|
GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
GstFileSrc *src;
|
||||||
int ret;
|
int ret;
|
||||||
GstBuffer *buf;
|
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
gsize size;
|
|
||||||
|
src = GST_FILE_SRC_CAST (basesrc);
|
||||||
|
|
||||||
if (G_UNLIKELY (src->read_position != offset)) {
|
if (G_UNLIKELY (src->read_position != offset)) {
|
||||||
off_t res;
|
off_t res;
|
||||||
|
@ -343,39 +344,31 @@ gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length,
|
||||||
src->read_position = offset;
|
src->read_position = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = gst_buffer_new_and_alloc (length);
|
data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
|
||||||
if (G_UNLIKELY (buf == NULL && length > 0))
|
|
||||||
goto alloc_failed;
|
|
||||||
|
|
||||||
/* No need to read anything if length is 0 */
|
GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x",
|
||||||
if (length > 0) {
|
length, offset);
|
||||||
data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x",
|
ret = read (src->fd, data, length);
|
||||||
length, offset);
|
if (G_UNLIKELY (ret < 0))
|
||||||
ret = read (src->fd, data, length);
|
goto could_not_read;
|
||||||
if (G_UNLIKELY (ret < 0))
|
|
||||||
goto could_not_read;
|
|
||||||
|
|
||||||
/* seekable regular files should have given us what we expected */
|
/* seekable regular files should have given us what we expected */
|
||||||
if (G_UNLIKELY ((guint) ret < length && src->seekable))
|
if (G_UNLIKELY ((guint) ret < length && src->seekable))
|
||||||
goto unexpected_eos;
|
goto unexpected_eos;
|
||||||
|
|
||||||
/* other files should eos if they read 0 and more was requested */
|
/* other files should eos if they read 0 and more was requested */
|
||||||
if (G_UNLIKELY (ret == 0 && length > 0))
|
if (G_UNLIKELY (ret == 0))
|
||||||
goto eos;
|
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 (buf) = offset;
|
||||||
GST_BUFFER_OFFSET_END (buf) = offset + length;
|
GST_BUFFER_OFFSET_END (buf) = offset + length;
|
||||||
|
|
||||||
src->read_position += length;
|
src->read_position += length;
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = buf;
|
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
@ -385,16 +378,10 @@ seek_failed:
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
|
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
alloc_failed:
|
|
||||||
{
|
|
||||||
GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", length);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
could_not_read:
|
could_not_read:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
|
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
|
||||||
gst_buffer_unmap (buf, data, 0);
|
gst_buffer_unmap (buf, data, 0);
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
unexpected_eos:
|
unexpected_eos:
|
||||||
|
@ -402,32 +389,16 @@ unexpected_eos:
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
|
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
|
||||||
("unexpected end of file."));
|
("unexpected end of file."));
|
||||||
gst_buffer_unmap (buf, data, 0);
|
gst_buffer_unmap (buf, data, 0);
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
eos:
|
eos:
|
||||||
{
|
{
|
||||||
GST_DEBUG ("non-regular file hits EOS");
|
GST_DEBUG ("non-regular file hits EOS");
|
||||||
gst_buffer_unmap (buf, data, 0);
|
gst_buffer_unmap (buf, data, 0);
|
||||||
gst_buffer_unref (buf);
|
|
||||||
return GST_FLOW_UNEXPECTED;
|
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
|
static gboolean
|
||||||
gst_file_src_query (GstBaseSrc * basesrc, GstQuery * query)
|
gst_file_src_query (GstBaseSrc * basesrc, GstQuery * query)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue