mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 05:59:10 +00:00
Fix seeking on gnomevfssrc
Original commit message from CVS: Fix seeking on gnomevfssrc
This commit is contained in:
parent
cc5d778695
commit
37e7a7c5e2
1 changed files with 91 additions and 31 deletions
|
@ -72,7 +72,6 @@ struct _GstGnomeVFSSrc {
|
||||||
/* handle */
|
/* handle */
|
||||||
GnomeVFSHandle *handle;
|
GnomeVFSHandle *handle;
|
||||||
/* Seek stuff */
|
/* Seek stuff */
|
||||||
gboolean seek_happened;
|
|
||||||
gboolean need_flush;
|
gboolean need_flush;
|
||||||
|
|
||||||
/* local filename */
|
/* local filename */
|
||||||
|
@ -117,19 +116,24 @@ enum {
|
||||||
|
|
||||||
GType gst_gnomevfssrc_get_type(void);
|
GType gst_gnomevfssrc_get_type(void);
|
||||||
|
|
||||||
static void gst_gnomevfssrc_class_init(GstGnomeVFSSrcClass *klass);
|
static void gst_gnomevfssrc_class_init (GstGnomeVFSSrcClass *klass);
|
||||||
static void gst_gnomevfssrc_init(GstGnomeVFSSrc *gnomevfssrc);
|
static void gst_gnomevfssrc_init (GstGnomeVFSSrc *gnomevfssrc);
|
||||||
|
|
||||||
static void gst_gnomevfssrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
static void gst_gnomevfssrc_set_property (GObject *object, guint prop_id,
|
||||||
static void gst_gnomevfssrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
|
const GValue *value, GParamSpec *pspec);
|
||||||
|
static void gst_gnomevfssrc_get_property (GObject *object, guint prop_id,
|
||||||
|
GValue *value, GParamSpec *pspec);
|
||||||
|
|
||||||
static GstBuffer *gst_gnomevfssrc_get(GstPad *pad);
|
static GstBuffer* gst_gnomevfssrc_get (GstPad *pad);
|
||||||
|
|
||||||
static GstElementStateReturn gst_gnomevfssrc_change_state(GstElement *element);
|
static GstElementStateReturn
|
||||||
|
gst_gnomevfssrc_change_state (GstElement *element);
|
||||||
|
|
||||||
static void gst_gnomevfssrc_close_file(GstGnomeVFSSrc *src);
|
static void gst_gnomevfssrc_close_file (GstGnomeVFSSrc *src);
|
||||||
static gboolean gst_gnomevfssrc_open_file(GstGnomeVFSSrc *src);
|
static gboolean gst_gnomevfssrc_open_file (GstGnomeVFSSrc *src);
|
||||||
static gboolean gst_gnomevfssrc_srcpad_event (GstPad *pad, GstEvent *event);
|
static gboolean gst_gnomevfssrc_srcpad_event (GstPad *pad, GstEvent *event);
|
||||||
|
static gboolean gst_gnomevfssrc_srcpad_query (GstPad *pad, GstPadQueryType type,
|
||||||
|
GstFormat *format, gint64 *value);
|
||||||
|
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
@ -193,6 +197,8 @@ static void gst_gnomevfssrc_init(GstGnomeVFSSrc *gnomevfssrc)
|
||||||
gst_pad_set_get_function(gnomevfssrc->srcpad, gst_gnomevfssrc_get);
|
gst_pad_set_get_function(gnomevfssrc->srcpad, gst_gnomevfssrc_get);
|
||||||
gst_pad_set_event_function (gnomevfssrc->srcpad,
|
gst_pad_set_event_function (gnomevfssrc->srcpad,
|
||||||
gst_gnomevfssrc_srcpad_event);
|
gst_gnomevfssrc_srcpad_event);
|
||||||
|
gst_pad_set_query_function (gnomevfssrc->srcpad,
|
||||||
|
gst_gnomevfssrc_srcpad_query);
|
||||||
gst_element_add_pad(GST_ELEMENT(gnomevfssrc), gnomevfssrc->srcpad);
|
gst_element_add_pad(GST_ELEMENT(gnomevfssrc), gnomevfssrc->srcpad);
|
||||||
|
|
||||||
gnomevfssrc->filename = NULL;
|
gnomevfssrc->filename = NULL;
|
||||||
|
@ -335,16 +341,24 @@ static GstBuffer *gst_gnomevfssrc_get(GstPad *pad)
|
||||||
GST_BUFFER_SIZE (buf) = src->bytes_per_read;
|
GST_BUFFER_SIZE (buf) = src->bytes_per_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src->new_seek)
|
||||||
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
|
||||||
|
GST_DEBUG (0,"new seek %lld", src->curoffset);
|
||||||
|
src->new_seek = FALSE;
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_EVENT, "gnomevfssrc sending discont");
|
||||||
|
event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL);
|
||||||
|
GST_EVENT_DISCONT_FLUSH (event) = src->need_flush;
|
||||||
|
src->need_flush = FALSE;
|
||||||
|
return GST_BUFFER (event);
|
||||||
|
}
|
||||||
|
|
||||||
src->curoffset += GST_BUFFER_SIZE (buf);
|
src->curoffset += GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
g_object_notify ((GObject*) src, "offset");
|
g_object_notify ((GObject*) src, "offset");
|
||||||
|
|
||||||
if (src->new_seek)
|
|
||||||
{
|
|
||||||
/* FIXME do a discont, flush event */
|
|
||||||
GST_DEBUG (0,"new seek");
|
|
||||||
src->new_seek = FALSE;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* allocate the space for the buffer data */
|
/* allocate the space for the buffer data */
|
||||||
GST_BUFFER_DATA(buf) = g_malloc(src->bytes_per_read);
|
GST_BUFFER_DATA(buf) = g_malloc(src->bytes_per_read);
|
||||||
|
@ -352,12 +366,15 @@ static GstBuffer *gst_gnomevfssrc_get(GstPad *pad)
|
||||||
|
|
||||||
if (src->new_seek)
|
if (src->new_seek)
|
||||||
{
|
{
|
||||||
result = gnome_vfs_seek(src->handle,
|
GstEvent *event;
|
||||||
GNOME_VFS_SEEK_START, src->curoffset);
|
|
||||||
GST_DEBUG(0, "new_seek: %s",
|
|
||||||
gnome_vfs_result_to_string(result));
|
|
||||||
/* FIXME do a discont, flush event */
|
|
||||||
src->new_seek = FALSE;
|
src->new_seek = FALSE;
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_EVENT, "gnomevfssrc sending discont");
|
||||||
|
event = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES, src->curoffset, NULL);
|
||||||
|
GST_EVENT_DISCONT_FLUSH (event) = src->need_flush;
|
||||||
|
src->need_flush = FALSE;
|
||||||
|
return GST_BUFFER (event);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = gnome_vfs_read(src->handle, GST_BUFFER_DATA(buf),
|
result = gnome_vfs_read(src->handle, GST_BUFFER_DATA(buf),
|
||||||
|
@ -381,6 +398,8 @@ static GstBuffer *gst_gnomevfssrc_get(GstPad *pad)
|
||||||
g_object_notify ((GObject*) src, "offset");
|
g_object_notify ((GObject*) src, "offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_BUFFER_TIMESTAMP (buf) = -1;
|
||||||
|
|
||||||
/* we're done, return the buffer */
|
/* we're done, return the buffer */
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -461,6 +480,7 @@ static gboolean gst_gnomevfssrc_open_file(GstGnomeVFSSrc *src)
|
||||||
else
|
else
|
||||||
src->size = info->size;
|
src->size = info->size;
|
||||||
|
|
||||||
|
GST_DEBUG(0, "size %lld", src->size);
|
||||||
g_object_notify (G_OBJECT (src), "filesize");
|
g_object_notify (G_OBJECT (src), "filesize");
|
||||||
|
|
||||||
gnome_vfs_file_info_unref(info);
|
gnome_vfs_file_info_unref(info);
|
||||||
|
@ -509,20 +529,20 @@ static GstElementStateReturn gst_gnomevfssrc_change_state(GstElement *element)
|
||||||
GST_STATE_FAILURE);
|
GST_STATE_FAILURE);
|
||||||
|
|
||||||
switch (GST_STATE_TRANSITION (element)) {
|
switch (GST_STATE_TRANSITION (element)) {
|
||||||
case GST_STATE_NULL_TO_READY:
|
case GST_STATE_READY_TO_PAUSED:
|
||||||
if (!GST_FLAG_IS_SET(element, GST_GNOMEVFSSRC_OPEN)) {
|
if (!GST_FLAG_IS_SET(element, GST_GNOMEVFSSRC_OPEN)) {
|
||||||
if (!gst_gnomevfssrc_open_file
|
if (!gst_gnomevfssrc_open_file
|
||||||
(GST_GNOMEVFSSRC(element)))
|
(GST_GNOMEVFSSRC(element)))
|
||||||
return GST_STATE_FAILURE;
|
return GST_STATE_FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_NULL:
|
case GST_STATE_PAUSED_TO_READY:
|
||||||
if (GST_FLAG_IS_SET(element, GST_GNOMEVFSSRC_OPEN))
|
if (GST_FLAG_IS_SET(element, GST_GNOMEVFSSRC_OPEN))
|
||||||
gst_gnomevfssrc_close_file(GST_GNOMEVFSSRC
|
gst_gnomevfssrc_close_file(GST_GNOMEVFSSRC
|
||||||
(element));
|
(element));
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_PAUSED:
|
case GST_STATE_NULL_TO_READY:
|
||||||
case GST_STATE_PAUSED_TO_READY:
|
case GST_STATE_READY_TO_NULL:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -549,6 +569,32 @@ static gboolean plugin_init(GModule *module, GstPlugin *plugin)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_gnomevfssrc_srcpad_query (GstPad *pad, GstPadQueryType type,
|
||||||
|
GstFormat *format, gint64 *value)
|
||||||
|
{
|
||||||
|
GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case GST_PAD_QUERY_TOTAL:
|
||||||
|
if (*format != GST_FORMAT_BYTES) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*value = src->size;
|
||||||
|
break;
|
||||||
|
case GST_PAD_QUERY_POSITION:
|
||||||
|
if (*format != GST_FORMAT_BYTES) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*value = src->curoffset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gnomevfssrc_srcpad_event (GstPad *pad, GstEvent *event)
|
gst_gnomevfssrc_srcpad_event (GstPad *pad, GstEvent *event)
|
||||||
{
|
{
|
||||||
|
@ -557,27 +603,41 @@ gst_gnomevfssrc_srcpad_event (GstPad *pad, GstEvent *event)
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_SEEK:
|
case GST_EVENT_SEEK:
|
||||||
{
|
{
|
||||||
|
gint64 desired_offset;
|
||||||
|
|
||||||
if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES) {
|
if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
switch (GST_EVENT_SEEK_METHOD (event)) {
|
switch (GST_EVENT_SEEK_METHOD (event)) {
|
||||||
case GST_SEEK_METHOD_SET:
|
case GST_SEEK_METHOD_SET:
|
||||||
src->curoffset = (guint64) GST_EVENT_SEEK_OFFSET (event);
|
desired_offset = (guint64) GST_EVENT_SEEK_OFFSET (event);
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_METHOD_CUR:
|
case GST_SEEK_METHOD_CUR:
|
||||||
src->curoffset += GST_EVENT_SEEK_OFFSET (event);
|
desired_offset = src->curoffset + GST_EVENT_SEEK_OFFSET (event);
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_METHOD_END:
|
case GST_SEEK_METHOD_END:
|
||||||
src->curoffset = src->size - ABS (GST_EVENT_SEEK_OFFSET (event));
|
desired_offset = src->size - ABS (GST_EVENT_SEEK_OFFSET (event));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
g_object_notify (G_OBJECT (src), "offset");
|
if (!src->is_local) {
|
||||||
src->seek_happened = TRUE;
|
GnomeVFSResult result;
|
||||||
|
|
||||||
|
result = gnome_vfs_seek(src->handle,
|
||||||
|
GNOME_VFS_SEEK_START, desired_offset);
|
||||||
|
GST_DEBUG(0, "new_seek: %s",
|
||||||
|
gnome_vfs_result_to_string(result));
|
||||||
|
|
||||||
|
if (result != GNOME_VFS_OK) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src->curoffset = desired_offset;
|
||||||
|
src->new_seek = TRUE;
|
||||||
src->need_flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH;
|
src->need_flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH;
|
||||||
/* push a discontinuous event? */
|
g_object_notify (G_OBJECT (src), "offset");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_EVENT_FLUSH:
|
case GST_EVENT_FLUSH:
|
||||||
|
|
Loading…
Reference in a new issue