From 6340b23cc004ce6e9e2d2fc6ba037363a337001e Mon Sep 17 00:00:00 2001 From: Erik Walthinsen Date: Fri, 21 Jul 2000 03:57:51 +0000 Subject: [PATCH] Brought standard elements in line with new state management system. Original commit message from CVS: Brought standard elements in line with new state management system. --- gst/elements/gstasyncdisksrc.c | 38 ++++++++++----------- gst/elements/gstaudiosink.c | 54 ++++++++---------------------- gst/elements/gstaudiosink.h | 5 +++ gst/elements/gstaudiosrc.c | 34 ++++++++++--------- gst/elements/gstaudiosrc.h | 5 +++ gst/elements/gstdisksrc.c | 50 ++++++++++++++------------- gst/elements/gstdisksrc.h | 3 +- gst/elements/gstfdsrc.c | 7 ++-- gst/elements/gsthttpsrc.c | 44 ++++++++++++------------ gst/elements/gsthttpsrc.h | 5 +++ gst/elements/gstpipefilter.c | 28 +++++++--------- gst/elements/gstpipefilter.h | 10 +++--- plugins/elements/gstasyncdisksrc.c | 38 ++++++++++----------- plugins/elements/gstaudiosink.c | 54 ++++++++---------------------- plugins/elements/gstaudiosink.h | 5 +++ plugins/elements/gstaudiosrc.c | 34 ++++++++++--------- plugins/elements/gstaudiosrc.h | 5 +++ plugins/elements/gstdisksrc.c | 50 ++++++++++++++------------- plugins/elements/gstdisksrc.h | 3 +- plugins/elements/gstfdsrc.c | 7 ++-- plugins/elements/gsthttpsrc.c | 44 ++++++++++++------------ plugins/elements/gsthttpsrc.h | 5 +++ plugins/elements/gstpipefilter.c | 28 +++++++--------- plugins/elements/gstpipefilter.h | 10 +++--- 24 files changed, 266 insertions(+), 300 deletions(-) diff --git a/gst/elements/gstasyncdisksrc.c b/gst/elements/gstasyncdisksrc.c index 1d534a4578..9443db0c39 100644 --- a/gst/elements/gstasyncdisksrc.c +++ b/gst/elements/gstasyncdisksrc.c @@ -59,8 +59,7 @@ static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_asyncdisksrc_push(GstSrc *src); static void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset, gulong size); -static gboolean gst_asyncdisksrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element); static GstSrcClass *parent_class = NULL; @@ -142,17 +141,16 @@ static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: /* the element must be stopped in order to do this */ - g_return_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN)); + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); if (src->filename) g_free(src->filename); /* clear the filename if we get a NULL (is that possible?) */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->filename = NULL; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new filename */ } else { src->filename = g_strdup(GTK_VALUE_STRING(*arg)); - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); } break; case ARG_BYTESPERREAD: @@ -251,7 +249,7 @@ void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) { g_return_if_fail(src != NULL); g_return_if_fail(GST_IS_ASYNCDISKSRC(src)); - g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_READY)); asyncdisksrc = GST_ASYNCDISKSRC(src); /* deal with EOF state */ @@ -282,7 +280,7 @@ void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) { } -/* open the file and mmap it, necessary to go to RUNNING state */ +/* open the file and mmap it, necessary to go to READY state */ static gboolean gst_asyncdisksrc_open_file(GstAsyncDiskSrc *src) { g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN), FALSE); @@ -329,23 +327,21 @@ static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) { } -static gboolean gst_asyncdisksrc_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_ASYNCDISKSRC(element), FALSE); +static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element) { + g_return_val_if_fail(GST_IS_ASYNCDISKSRC(element),GST_STATE_FAILURE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) gst_asyncdisksrc_close_file(GST_ASYNCDISKSRC(element)); - break; - default: - break; + } else { + if (!GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) { + if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element))) + return GST_STATE_FAILURE; + } } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); - return TRUE; + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + + return GST_STATE_SUCCESS; } diff --git a/gst/elements/gstaudiosink.c b/gst/elements/gstaudiosink.c index be54778c7d..30da25f847 100644 --- a/gst/elements/gstaudiosink.c +++ b/gst/elements/gstaudiosink.c @@ -41,11 +41,7 @@ GstElementDetails gst_audiosink_details = { static gboolean gst_audiosink_open_audio(GstAudioSink *sink); static void gst_audiosink_close_audio(GstAudioSink *sink); -static gboolean gst_audiosink_start(GstElement *element, - GstElementState state); -static gboolean gst_audiosink_stop(GstElement *element); -static gboolean gst_audiosink_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_audiosink_change_state(GstElement *element); static void gst_audiosink_set_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_audiosink_get_arg(GtkObject *object,GtkArg *arg,guint id); @@ -131,8 +127,6 @@ gst_audiosink_class_init(GstAudioSinkClass *klass) { gtk_object_class_add_signals(gtkobject_class,gst_audiosink_signals, LAST_SIGNAL); - gstelement_class->start = gst_audiosink_start; - gstelement_class->stop = gst_audiosink_stop; gstelement_class->change_state = gst_audiosink_change_state; } @@ -177,7 +171,6 @@ void gst_audiosink_sync_parms(GstAudioSink *audiosink) { GstElement *gst_audiosink_new(gchar *name) { GstElement *audiosink = GST_ELEMENT(gtk_type_new(GST_TYPE_AUDIOSINK)); gst_element_set_name(GST_ELEMENT(audiosink),name); - gst_element_set_state(GST_ELEMENT(audiosink),GST_STATE_COMPLETE); return audiosink; } @@ -335,42 +328,23 @@ static void gst_audiosink_close_audio(GstAudioSink *sink) { g_print("audiosink: closed sound device\n"); } -static gboolean gst_audiosink_start(GstElement *element, - GstElementState state) { + +static GstElementStateReturn gst_audiosink_change_state(GstElement *element) { g_return_val_if_fail(GST_IS_AUDIOSINK(element), FALSE); - if (gst_audiosink_open_audio(GST_AUDIOSINK(element)) == TRUE) { - gst_element_set_state(element,GST_STATE_RUNNING | state); - return TRUE; - } - return FALSE; -} - -static gboolean gst_audiosink_stop(GstElement *element) { - g_return_val_if_fail(GST_IS_AUDIOSINK(element), FALSE); - - gst_audiosink_close_audio(GST_AUDIOSINK(element)); - gst_element_set_state(element,~GST_STATE_RUNNING); - return TRUE; -} - -static gboolean gst_audiosink_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_AUDIOSINK(element), FALSE); - - switch (state) { - case GST_STATE_RUNNING: - if (!gst_audiosink_open_audio(GST_AUDIOSINK(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_AUDIOSINK_OPEN)) gst_audiosink_close_audio(GST_AUDIOSINK(element)); - break; - default: - break; - } + /* otherwise (READY or higher) we need to open the sound card */ + } else { + if (!GST_FLAG_IS_SET(element,GST_AUDIOSINK_OPEN)) { + if (!gst_audiosink_open_audio(GST_AUDIOSINK(element))) + return GST_STATE_FAILURE; + } + } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return GST_ELEMENT_CLASS(parent_class)->change_state(element); return TRUE; } diff --git a/gst/elements/gstaudiosink.h b/gst/elements/gstaudiosink.h index 26a1041032..45ffa1fac6 100644 --- a/gst/elements/gstaudiosink.h +++ b/gst/elements/gstaudiosink.h @@ -46,6 +46,11 @@ GstElementDetails gst_audiosink_details; #define GST_IS_AUDIOSINK_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_AUDIOSINK_OPEN = (1 << 16), +} GstAudioSinkFlags; + typedef struct _GstAudioSink GstAudioSink; typedef struct _GstAudioSinkClass GstAudioSinkClass; diff --git a/gst/elements/gstaudiosrc.c b/gst/elements/gstaudiosrc.c index 670657ff33..38ad86f169 100644 --- a/gst/elements/gstaudiosrc.c +++ b/gst/elements/gstaudiosrc.c @@ -57,8 +57,8 @@ static void gst_audiosrc_class_init(GstAudioSrcClass *klass); static void gst_audiosrc_init(GstAudioSrc *audiosrc); static void gst_audiosrc_set_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_audiosrc_get_arg(GtkObject *object,GtkArg *arg,guint id); -static gboolean gst_audiosrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_audiosrc_change_state(GstElement *element); + static void gst_audiosrc_close_audio(GstAudioSrc *src); static gboolean gst_audiosrc_open_audio(GstAudioSrc *src); void gst_audiosrc_sync_parms(GstAudioSrc *audiosrc); @@ -224,29 +224,28 @@ static void gst_audiosrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { } } -static gboolean gst_audiosrc_change_state(GstElement *element, - GstElementState state) { +static GstElementStateReturn gst_audiosrc_change_state(GstElement *element) { g_return_val_if_fail(GST_IS_AUDIOSRC(element), FALSE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_audiosrc_open_audio(GST_AUDIOSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_AUDIOSRC_OPEN)) gst_audiosrc_close_audio(GST_AUDIOSRC(element)); - break; - default: - break; + /* otherwise (READY or higher) we need to open the sound card */ + } else { + if (!GST_FLAG_IS_SET(element,GST_AUDIOSRC_OPEN)) { + if (!gst_audiosrc_open_audio(GST_AUDIOSRC(element))) + return GST_STATE_FAILURE; + } } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return GST_ELEMENT_CLASS(parent_class)->change_state(element); return TRUE; } static gboolean gst_audiosrc_open_audio(GstAudioSrc *src) { - g_return_val_if_fail(src->fd == -1, FALSE); + g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_AUDIOSRC_OPEN), FALSE); /* first try to open the sound card */ src->fd = open("/dev/dsp",O_RDONLY); @@ -260,6 +259,7 @@ static gboolean gst_audiosrc_open_audio(GstAudioSrc *src) { /* set card state */ gst_audiosrc_sync_parms(src); DEBUG("opened audio\n"); + GST_FLAG_SET(src,GST_AUDIOSRC_OPEN); return TRUE; } @@ -267,10 +267,12 @@ static gboolean gst_audiosrc_open_audio(GstAudioSrc *src) { } static void gst_audiosrc_close_audio(GstAudioSrc *src) { - g_return_if_fail(src->fd >= 0); + g_return_if_fail(GST_FLAG_IS_SET(src,GST_AUDIOSRC_OPEN)); close(src->fd); src->fd = -1; + + GST_FLAG_UNSET(src,GST_AUDIOSRC_OPEN); } void gst_audiosrc_sync_parms(GstAudioSrc *audiosrc) { diff --git a/gst/elements/gstaudiosrc.h b/gst/elements/gstaudiosrc.h index bd2a9c6a60..de595b2e59 100644 --- a/gst/elements/gstaudiosrc.h +++ b/gst/elements/gstaudiosrc.h @@ -46,6 +46,11 @@ GstElementDetails gst_audiosrc_details; #define GST_IS_AUDIOSRC_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSRC))) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_AUDIOSRC_OPEN = (1 < 16), +} GstAudioSrcFlags; + typedef struct _GstAudioSrc GstAudioSrc; typedef struct _GstAudioSrcClass GstAudioSrcClass; diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c index 5e852f836f..0484a09cd7 100644 --- a/gst/elements/gstdisksrc.c +++ b/gst/elements/gstdisksrc.c @@ -57,8 +57,7 @@ static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_disksrc_push(GstSrc *src); //static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size); -static gboolean gst_disksrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_disksrc_change_state(GstElement *element); static GstSrcClass *parent_class = NULL; @@ -138,18 +137,17 @@ static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: - /* the element must be stopped in order to do this */ -// g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + /* the element must not be playing in order to do this */ + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); if (src->filename) g_free(src->filename); /* clear the filename if we get a NULL (is that possible?) */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->filename = NULL; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new filename */ } else { - src->filename = g_strdup(GTK_VALUE_STRING(*arg)); - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); + src->filename = g_strdup(GTK_VALUE_STRING(*arg)); } break; case ARG_BYTESPERREAD: @@ -199,6 +197,7 @@ void gst_disksrc_push(GstSrc *src) { g_return_if_fail(src != NULL); g_return_if_fail(GST_IS_DISKSRC(src)); g_return_if_fail(GST_FLAG_IS_SET(src,GST_DISKSRC_OPEN)); + g_return_if_fail(GST_STATE(src) >= GST_STATE_READY); disksrc = GST_DISKSRC(src); /* create the buffer */ @@ -237,7 +236,7 @@ void gst_disksrc_push(GstSrc *src) { GST_BUFFER_SIZE(buf) = readbytes; disksrc->curoffset += readbytes; - DEBUG("pushing with offset %lu\n", GST_BUFFER_OFFSET(buf)); + DEBUG("pushing with offset %d\n", GST_BUFFER_OFFSET(buf)); /* we're done, push the buffer off now */ gst_pad_push(disksrc->srcpad,buf); } @@ -246,7 +245,9 @@ void gst_disksrc_push(GstSrc *src) { /* open the file, necessary to go to RUNNING state */ static gboolean gst_disksrc_open_file(GstDiskSrc *src) { struct stat f_stat; + g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_DISKSRC_OPEN), FALSE); + g_return_val_if_fail(src->filename != NULL, FALSE); /* open the file */ src->fd = open(src->filename,O_RDONLY); @@ -282,23 +283,24 @@ static void gst_disksrc_close_file(GstDiskSrc *src) { GST_FLAG_UNSET(src,GST_DISKSRC_OPEN); } -static gboolean gst_disksrc_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_DISKSRC(element), FALSE); +static GstElementStateReturn gst_disksrc_change_state(GstElement *element) { + g_return_val_if_fail(GST_IS_DISKSRC(element),GST_STATE_FAILURE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_disksrc_open_file(GST_DISKSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_DISKSRC_OPEN)) gst_disksrc_close_file(GST_DISKSRC(element)); - break; - default: - break; - } - + /* otherwise (READY or higher) we need to open the file */ + } else { + if (!GST_FLAG_IS_SET(element,GST_DISKSRC_OPEN)) { + if (!gst_disksrc_open_file(GST_DISKSRC(element))) + return GST_STATE_FAILURE; + } + } + + /* if we haven't failed already, give the parent class a chance to ;-) */ if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); - return TRUE; + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + + return GST_STATE_SUCCESS; } diff --git a/gst/elements/gstdisksrc.h b/gst/elements/gstdisksrc.h index 95c66b32ae..26afb42658 100644 --- a/gst/elements/gstdisksrc.h +++ b/gst/elements/gstdisksrc.h @@ -58,9 +58,8 @@ struct _GstDiskSrc { /* pads */ GstPad *srcpad; - /* filename */ + /* file state */ gchar *filename; - /* fd */ gint fd; gulong curoffset; /* current offset in file */ diff --git a/gst/elements/gstfdsrc.c b/gst/elements/gstfdsrc.c index 085f755bcb..e88b9c5530 100644 --- a/gst/elements/gstfdsrc.c +++ b/gst/elements/gstfdsrc.c @@ -129,18 +129,17 @@ static void gst_fdsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: - /* the element must be stopped in order to do this */ - g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + /* the element must not be playing in order to do this */ + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); /* if we get a NULL, consider it to be a fd of 0 */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->fd = 0; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new filename */ } else { if (sscanf(GTK_VALUE_STRING(*arg),"%d",&fd)) src->fd = fd; - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); } break; case ARG_BYTESPERREAD: diff --git a/gst/elements/gsthttpsrc.c b/gst/elements/gsthttpsrc.c index 094ed07680..725b80534b 100644 --- a/gst/elements/gsthttpsrc.c +++ b/gst/elements/gsthttpsrc.c @@ -39,8 +39,7 @@ GstElementDetails gst_httpsrc_details = { static void gst_httpsrc_push(GstSrc *src); static gboolean gst_httpsrc_open_url(GstHttpSrc *src); static void gst_httpsrc_close_url(GstHttpSrc *src); -static gboolean gst_httpsrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_httpsrc_change_state(GstElement *element); /* HttpSrc signals and args */ @@ -155,8 +154,7 @@ static void gst_httpsrc_push(GstSrc *src) { static gboolean gst_httpsrc_open_url(GstHttpSrc *httpsrc) { gint status; - g_return_val_if_fail(httpsrc != NULL, FALSE); - g_return_val_if_fail(GST_IS_HTTPSRC(httpsrc), FALSE); + g_return_val_if_fail(!GST_FLAG_IS_SET(httpsrc,GST_HTTPSRC_OPEN), FALSE); g_return_val_if_fail(httpsrc->url != NULL, FALSE); httpsrc->request = ghttp_request_new(); @@ -175,15 +173,20 @@ static gboolean gst_httpsrc_open_url(GstHttpSrc *httpsrc) { /* get the fd so we can read data ourselves */ httpsrc->fd = ghttp_get_socket(httpsrc->request); + GST_FLAG_SET(httpsrc,GST_HTTPSRC_OPEN); return TRUE; } /* unmap and close the file */ static void gst_httpsrc_close_url(GstHttpSrc *src) { + g_return_if_fail(GST_FLAG_IS_SET(src,GST_HTTPSRC_OPEN)); + g_return_if_fail(src->fd > 0); close(src->fd); src->fd = 0; + + GST_FLAG_UNSET(src,GST_HTTPSRC_OPEN); } static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { @@ -195,18 +198,17 @@ static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: - /* the element must be stopped in order to do this */ - g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + /* the element must not be playing in order to do this */ + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); if (src->url) g_free(src->url); /* clear the url if we get a NULL (is that possible?) */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->url = NULL; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new url */ } else { src->url = g_strdup(GTK_VALUE_STRING(*arg)); - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); } break; case ARG_BYTESPERREAD: @@ -237,24 +239,20 @@ static void gst_httpsrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { } } -static gboolean gst_httpsrc_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_HTTPSRC(element), FALSE); +static GstElementStateReturn gst_httpsrc_change_state(GstElement *element) { + g_return_val_if_fail(GST_IS_HTTPSRC(element),GST_STATE_FAILURE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_httpsrc_open_url(GST_HTTPSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_HTTPSRC_OPEN)) gst_httpsrc_close_url(GST_HTTPSRC(element)); - break; - default: - break; + } else { + if (!GST_FLAG_IS_SET(element,GST_HTTPSRC_OPEN)) { + if (!gst_httpsrc_open_url(GST_HTTPSRC(element))) + return GST_STATE_FAILURE; + } } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); - return TRUE; + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + return GST_STATE_SUCCESS; } - diff --git a/gst/elements/gsthttpsrc.h b/gst/elements/gsthttpsrc.h index ae55f293f2..cd395cc76c 100644 --- a/gst/elements/gsthttpsrc.h +++ b/gst/elements/gsthttpsrc.h @@ -47,6 +47,11 @@ GstElementDetails gst_httpsrc_details; #define GST_IS_HTTPSRC_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_HTTPSRC))) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_HTTPSRC_OPEN = (1 << 16), +} GstHttpSrcFlags; + typedef struct _GstHttpSrc GstHttpSrc; typedef struct _GstHttpSrcClass GstHttpSrcClass; diff --git a/gst/elements/gstpipefilter.c b/gst/elements/gstpipefilter.c index 64b4dbb02f..d5bbaf6d21 100644 --- a/gst/elements/gstpipefilter.c +++ b/gst/elements/gstpipefilter.c @@ -59,8 +59,7 @@ static void gst_pipefilter_get_arg(GtkObject *object,GtkArg *arg,guint id); void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf); -static gboolean gst_pipefilter_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_pipefilter_change_state(GstElement *element); static GstFilterClass *parent_class = NULL; //static guint gst_pipefilter_signals[LAST_SIGNAL] = { 0 }; @@ -287,23 +286,22 @@ static void gst_pipefilter_close_file(GstPipefilter *src) { GST_FLAG_UNSET(src,GST_PIPEFILTER_OPEN); } -static gboolean gst_pipefilter_change_state(GstElement *element, - GstElementState state) { +static GstElementStateReturn gst_pipefilter_change_state(GstElement *element) { g_return_val_if_fail(GST_IS_PIPEFILTER(element), FALSE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_pipefilter_open_file(GST_PIPEFILTER(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_PIPEFILTER_OPEN)) gst_pipefilter_close_file(GST_PIPEFILTER(element)); - break; - default: - break; - } + /* otherwise (READY or higher) we need to open the file */ + } else { + if (!GST_FLAG_IS_SET(element,GST_PIPEFILTER_OPEN)) { + if (!gst_disksrc_open_file(GST_PIPEFILTER(element))) + return GST_STATE_FAILURE; + } + } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return GST_ELEMENT_CLASS(parent_class)->change_state(element); return TRUE; } diff --git a/gst/elements/gstpipefilter.h b/gst/elements/gstpipefilter.h index 5243643e80..edd1d759a3 100644 --- a/gst/elements/gstpipefilter.h +++ b/gst/elements/gstpipefilter.h @@ -33,11 +33,6 @@ extern "C" { GstElementDetails gst_pipefilter_details; -// NOTE: per-element flags start with 16 for now -typedef enum { - GST_PIPEFILTER_OPEN = (1 << 16), -} GstPipefilterFlags; - #define GST_TYPE_PIPEFILTER \ (gst_pipefilter_get_type()) #define GST_PIPEFILTER(obj) \ @@ -49,6 +44,11 @@ typedef enum { #define GST_IS_PIPEFILTER_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PIPEFILTER)) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_PIPEFILTER_OPEN = (1 << 16 ), +} GstPipeFilterFlags; + typedef struct _GstPipefilter GstPipefilter; typedef struct _GstPipefilterClass GstPipefilterClass; diff --git a/plugins/elements/gstasyncdisksrc.c b/plugins/elements/gstasyncdisksrc.c index 1d534a4578..9443db0c39 100644 --- a/plugins/elements/gstasyncdisksrc.c +++ b/plugins/elements/gstasyncdisksrc.c @@ -59,8 +59,7 @@ static void gst_asyncdisksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_asyncdisksrc_push(GstSrc *src); static void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset, gulong size); -static gboolean gst_asyncdisksrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element); static GstSrcClass *parent_class = NULL; @@ -142,17 +141,16 @@ static void gst_asyncdisksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: /* the element must be stopped in order to do this */ - g_return_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN)); + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); if (src->filename) g_free(src->filename); /* clear the filename if we get a NULL (is that possible?) */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->filename = NULL; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new filename */ } else { src->filename = g_strdup(GTK_VALUE_STRING(*arg)); - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); } break; case ARG_BYTESPERREAD: @@ -251,7 +249,7 @@ void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) { g_return_if_fail(src != NULL); g_return_if_fail(GST_IS_ASYNCDISKSRC(src)); - g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + g_return_if_fail(GST_FLAG_IS_SET(src,GST_STATE_READY)); asyncdisksrc = GST_ASYNCDISKSRC(src); /* deal with EOF state */ @@ -282,7 +280,7 @@ void gst_asyncdisksrc_push_region(GstSrc *src,gulong offset,gulong size) { } -/* open the file and mmap it, necessary to go to RUNNING state */ +/* open the file and mmap it, necessary to go to READY state */ static gboolean gst_asyncdisksrc_open_file(GstAsyncDiskSrc *src) { g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_ASYNCDISKSRC_OPEN), FALSE); @@ -329,23 +327,21 @@ static void gst_asyncdisksrc_close_file(GstAsyncDiskSrc *src) { } -static gboolean gst_asyncdisksrc_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_ASYNCDISKSRC(element), FALSE); +static GstElementStateReturn gst_asyncdisksrc_change_state(GstElement *element) { + g_return_val_if_fail(GST_IS_ASYNCDISKSRC(element),GST_STATE_FAILURE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) gst_asyncdisksrc_close_file(GST_ASYNCDISKSRC(element)); - break; - default: - break; + } else { + if (!GST_FLAG_IS_SET(element,GST_ASYNCDISKSRC_OPEN)) { + if (!gst_asyncdisksrc_open_file(GST_ASYNCDISKSRC(element))) + return GST_STATE_FAILURE; + } } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); - return TRUE; + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + + return GST_STATE_SUCCESS; } diff --git a/plugins/elements/gstaudiosink.c b/plugins/elements/gstaudiosink.c index be54778c7d..30da25f847 100644 --- a/plugins/elements/gstaudiosink.c +++ b/plugins/elements/gstaudiosink.c @@ -41,11 +41,7 @@ GstElementDetails gst_audiosink_details = { static gboolean gst_audiosink_open_audio(GstAudioSink *sink); static void gst_audiosink_close_audio(GstAudioSink *sink); -static gboolean gst_audiosink_start(GstElement *element, - GstElementState state); -static gboolean gst_audiosink_stop(GstElement *element); -static gboolean gst_audiosink_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_audiosink_change_state(GstElement *element); static void gst_audiosink_set_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_audiosink_get_arg(GtkObject *object,GtkArg *arg,guint id); @@ -131,8 +127,6 @@ gst_audiosink_class_init(GstAudioSinkClass *klass) { gtk_object_class_add_signals(gtkobject_class,gst_audiosink_signals, LAST_SIGNAL); - gstelement_class->start = gst_audiosink_start; - gstelement_class->stop = gst_audiosink_stop; gstelement_class->change_state = gst_audiosink_change_state; } @@ -177,7 +171,6 @@ void gst_audiosink_sync_parms(GstAudioSink *audiosink) { GstElement *gst_audiosink_new(gchar *name) { GstElement *audiosink = GST_ELEMENT(gtk_type_new(GST_TYPE_AUDIOSINK)); gst_element_set_name(GST_ELEMENT(audiosink),name); - gst_element_set_state(GST_ELEMENT(audiosink),GST_STATE_COMPLETE); return audiosink; } @@ -335,42 +328,23 @@ static void gst_audiosink_close_audio(GstAudioSink *sink) { g_print("audiosink: closed sound device\n"); } -static gboolean gst_audiosink_start(GstElement *element, - GstElementState state) { + +static GstElementStateReturn gst_audiosink_change_state(GstElement *element) { g_return_val_if_fail(GST_IS_AUDIOSINK(element), FALSE); - if (gst_audiosink_open_audio(GST_AUDIOSINK(element)) == TRUE) { - gst_element_set_state(element,GST_STATE_RUNNING | state); - return TRUE; - } - return FALSE; -} - -static gboolean gst_audiosink_stop(GstElement *element) { - g_return_val_if_fail(GST_IS_AUDIOSINK(element), FALSE); - - gst_audiosink_close_audio(GST_AUDIOSINK(element)); - gst_element_set_state(element,~GST_STATE_RUNNING); - return TRUE; -} - -static gboolean gst_audiosink_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_AUDIOSINK(element), FALSE); - - switch (state) { - case GST_STATE_RUNNING: - if (!gst_audiosink_open_audio(GST_AUDIOSINK(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_AUDIOSINK_OPEN)) gst_audiosink_close_audio(GST_AUDIOSINK(element)); - break; - default: - break; - } + /* otherwise (READY or higher) we need to open the sound card */ + } else { + if (!GST_FLAG_IS_SET(element,GST_AUDIOSINK_OPEN)) { + if (!gst_audiosink_open_audio(GST_AUDIOSINK(element))) + return GST_STATE_FAILURE; + } + } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return GST_ELEMENT_CLASS(parent_class)->change_state(element); return TRUE; } diff --git a/plugins/elements/gstaudiosink.h b/plugins/elements/gstaudiosink.h index 26a1041032..45ffa1fac6 100644 --- a/plugins/elements/gstaudiosink.h +++ b/plugins/elements/gstaudiosink.h @@ -46,6 +46,11 @@ GstElementDetails gst_audiosink_details; #define GST_IS_AUDIOSINK_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_AUDIOSINK_OPEN = (1 << 16), +} GstAudioSinkFlags; + typedef struct _GstAudioSink GstAudioSink; typedef struct _GstAudioSinkClass GstAudioSinkClass; diff --git a/plugins/elements/gstaudiosrc.c b/plugins/elements/gstaudiosrc.c index 670657ff33..38ad86f169 100644 --- a/plugins/elements/gstaudiosrc.c +++ b/plugins/elements/gstaudiosrc.c @@ -57,8 +57,8 @@ static void gst_audiosrc_class_init(GstAudioSrcClass *klass); static void gst_audiosrc_init(GstAudioSrc *audiosrc); static void gst_audiosrc_set_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_audiosrc_get_arg(GtkObject *object,GtkArg *arg,guint id); -static gboolean gst_audiosrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_audiosrc_change_state(GstElement *element); + static void gst_audiosrc_close_audio(GstAudioSrc *src); static gboolean gst_audiosrc_open_audio(GstAudioSrc *src); void gst_audiosrc_sync_parms(GstAudioSrc *audiosrc); @@ -224,29 +224,28 @@ static void gst_audiosrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { } } -static gboolean gst_audiosrc_change_state(GstElement *element, - GstElementState state) { +static GstElementStateReturn gst_audiosrc_change_state(GstElement *element) { g_return_val_if_fail(GST_IS_AUDIOSRC(element), FALSE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_audiosrc_open_audio(GST_AUDIOSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_AUDIOSRC_OPEN)) gst_audiosrc_close_audio(GST_AUDIOSRC(element)); - break; - default: - break; + /* otherwise (READY or higher) we need to open the sound card */ + } else { + if (!GST_FLAG_IS_SET(element,GST_AUDIOSRC_OPEN)) { + if (!gst_audiosrc_open_audio(GST_AUDIOSRC(element))) + return GST_STATE_FAILURE; + } } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return GST_ELEMENT_CLASS(parent_class)->change_state(element); return TRUE; } static gboolean gst_audiosrc_open_audio(GstAudioSrc *src) { - g_return_val_if_fail(src->fd == -1, FALSE); + g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_AUDIOSRC_OPEN), FALSE); /* first try to open the sound card */ src->fd = open("/dev/dsp",O_RDONLY); @@ -260,6 +259,7 @@ static gboolean gst_audiosrc_open_audio(GstAudioSrc *src) { /* set card state */ gst_audiosrc_sync_parms(src); DEBUG("opened audio\n"); + GST_FLAG_SET(src,GST_AUDIOSRC_OPEN); return TRUE; } @@ -267,10 +267,12 @@ static gboolean gst_audiosrc_open_audio(GstAudioSrc *src) { } static void gst_audiosrc_close_audio(GstAudioSrc *src) { - g_return_if_fail(src->fd >= 0); + g_return_if_fail(GST_FLAG_IS_SET(src,GST_AUDIOSRC_OPEN)); close(src->fd); src->fd = -1; + + GST_FLAG_UNSET(src,GST_AUDIOSRC_OPEN); } void gst_audiosrc_sync_parms(GstAudioSrc *audiosrc) { diff --git a/plugins/elements/gstaudiosrc.h b/plugins/elements/gstaudiosrc.h index bd2a9c6a60..de595b2e59 100644 --- a/plugins/elements/gstaudiosrc.h +++ b/plugins/elements/gstaudiosrc.h @@ -46,6 +46,11 @@ GstElementDetails gst_audiosrc_details; #define GST_IS_AUDIOSRC_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSRC))) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_AUDIOSRC_OPEN = (1 < 16), +} GstAudioSrcFlags; + typedef struct _GstAudioSrc GstAudioSrc; typedef struct _GstAudioSrcClass GstAudioSrcClass; diff --git a/plugins/elements/gstdisksrc.c b/plugins/elements/gstdisksrc.c index 5e852f836f..0484a09cd7 100644 --- a/plugins/elements/gstdisksrc.c +++ b/plugins/elements/gstdisksrc.c @@ -57,8 +57,7 @@ static void gst_disksrc_get_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_disksrc_push(GstSrc *src); //static void gst_disksrc_push_region(GstSrc *src,gulong offset,gulong size); -static gboolean gst_disksrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_disksrc_change_state(GstElement *element); static GstSrcClass *parent_class = NULL; @@ -138,18 +137,17 @@ static void gst_disksrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: - /* the element must be stopped in order to do this */ -// g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + /* the element must not be playing in order to do this */ + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); if (src->filename) g_free(src->filename); /* clear the filename if we get a NULL (is that possible?) */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->filename = NULL; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new filename */ } else { - src->filename = g_strdup(GTK_VALUE_STRING(*arg)); - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); + src->filename = g_strdup(GTK_VALUE_STRING(*arg)); } break; case ARG_BYTESPERREAD: @@ -199,6 +197,7 @@ void gst_disksrc_push(GstSrc *src) { g_return_if_fail(src != NULL); g_return_if_fail(GST_IS_DISKSRC(src)); g_return_if_fail(GST_FLAG_IS_SET(src,GST_DISKSRC_OPEN)); + g_return_if_fail(GST_STATE(src) >= GST_STATE_READY); disksrc = GST_DISKSRC(src); /* create the buffer */ @@ -237,7 +236,7 @@ void gst_disksrc_push(GstSrc *src) { GST_BUFFER_SIZE(buf) = readbytes; disksrc->curoffset += readbytes; - DEBUG("pushing with offset %lu\n", GST_BUFFER_OFFSET(buf)); + DEBUG("pushing with offset %d\n", GST_BUFFER_OFFSET(buf)); /* we're done, push the buffer off now */ gst_pad_push(disksrc->srcpad,buf); } @@ -246,7 +245,9 @@ void gst_disksrc_push(GstSrc *src) { /* open the file, necessary to go to RUNNING state */ static gboolean gst_disksrc_open_file(GstDiskSrc *src) { struct stat f_stat; + g_return_val_if_fail(!GST_FLAG_IS_SET(src,GST_DISKSRC_OPEN), FALSE); + g_return_val_if_fail(src->filename != NULL, FALSE); /* open the file */ src->fd = open(src->filename,O_RDONLY); @@ -282,23 +283,24 @@ static void gst_disksrc_close_file(GstDiskSrc *src) { GST_FLAG_UNSET(src,GST_DISKSRC_OPEN); } -static gboolean gst_disksrc_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_DISKSRC(element), FALSE); +static GstElementStateReturn gst_disksrc_change_state(GstElement *element) { + g_return_val_if_fail(GST_IS_DISKSRC(element),GST_STATE_FAILURE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_disksrc_open_file(GST_DISKSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_DISKSRC_OPEN)) gst_disksrc_close_file(GST_DISKSRC(element)); - break; - default: - break; - } - + /* otherwise (READY or higher) we need to open the file */ + } else { + if (!GST_FLAG_IS_SET(element,GST_DISKSRC_OPEN)) { + if (!gst_disksrc_open_file(GST_DISKSRC(element))) + return GST_STATE_FAILURE; + } + } + + /* if we haven't failed already, give the parent class a chance to ;-) */ if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); - return TRUE; + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + + return GST_STATE_SUCCESS; } diff --git a/plugins/elements/gstdisksrc.h b/plugins/elements/gstdisksrc.h index 95c66b32ae..26afb42658 100644 --- a/plugins/elements/gstdisksrc.h +++ b/plugins/elements/gstdisksrc.h @@ -58,9 +58,8 @@ struct _GstDiskSrc { /* pads */ GstPad *srcpad; - /* filename */ + /* file state */ gchar *filename; - /* fd */ gint fd; gulong curoffset; /* current offset in file */ diff --git a/plugins/elements/gstfdsrc.c b/plugins/elements/gstfdsrc.c index 085f755bcb..e88b9c5530 100644 --- a/plugins/elements/gstfdsrc.c +++ b/plugins/elements/gstfdsrc.c @@ -129,18 +129,17 @@ static void gst_fdsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: - /* the element must be stopped in order to do this */ - g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + /* the element must not be playing in order to do this */ + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); /* if we get a NULL, consider it to be a fd of 0 */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->fd = 0; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new filename */ } else { if (sscanf(GTK_VALUE_STRING(*arg),"%d",&fd)) src->fd = fd; - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); } break; case ARG_BYTESPERREAD: diff --git a/plugins/elements/gsthttpsrc.c b/plugins/elements/gsthttpsrc.c index 094ed07680..725b80534b 100644 --- a/plugins/elements/gsthttpsrc.c +++ b/plugins/elements/gsthttpsrc.c @@ -39,8 +39,7 @@ GstElementDetails gst_httpsrc_details = { static void gst_httpsrc_push(GstSrc *src); static gboolean gst_httpsrc_open_url(GstHttpSrc *src); static void gst_httpsrc_close_url(GstHttpSrc *src); -static gboolean gst_httpsrc_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_httpsrc_change_state(GstElement *element); /* HttpSrc signals and args */ @@ -155,8 +154,7 @@ static void gst_httpsrc_push(GstSrc *src) { static gboolean gst_httpsrc_open_url(GstHttpSrc *httpsrc) { gint status; - g_return_val_if_fail(httpsrc != NULL, FALSE); - g_return_val_if_fail(GST_IS_HTTPSRC(httpsrc), FALSE); + g_return_val_if_fail(!GST_FLAG_IS_SET(httpsrc,GST_HTTPSRC_OPEN), FALSE); g_return_val_if_fail(httpsrc->url != NULL, FALSE); httpsrc->request = ghttp_request_new(); @@ -175,15 +173,20 @@ static gboolean gst_httpsrc_open_url(GstHttpSrc *httpsrc) { /* get the fd so we can read data ourselves */ httpsrc->fd = ghttp_get_socket(httpsrc->request); + GST_FLAG_SET(httpsrc,GST_HTTPSRC_OPEN); return TRUE; } /* unmap and close the file */ static void gst_httpsrc_close_url(GstHttpSrc *src) { + g_return_if_fail(GST_FLAG_IS_SET(src,GST_HTTPSRC_OPEN)); + g_return_if_fail(src->fd > 0); close(src->fd); src->fd = 0; + + GST_FLAG_UNSET(src,GST_HTTPSRC_OPEN); } static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { @@ -195,18 +198,17 @@ static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch(id) { case ARG_LOCATION: - /* the element must be stopped in order to do this */ - g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING)); + /* the element must not be playing in order to do this */ + g_return_if_fail(GST_STATE(src) < GST_STATE_PLAYING); if (src->url) g_free(src->url); /* clear the url if we get a NULL (is that possible?) */ if (GTK_VALUE_STRING(*arg) == NULL) { + gst_element_set_state(GST_ELEMENT(object),GST_STATE_NULL); src->url = NULL; - gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE); /* otherwise set the new url */ } else { src->url = g_strdup(GTK_VALUE_STRING(*arg)); - gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE); } break; case ARG_BYTESPERREAD: @@ -237,24 +239,20 @@ static void gst_httpsrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { } } -static gboolean gst_httpsrc_change_state(GstElement *element, - GstElementState state) { - g_return_val_if_fail(GST_IS_HTTPSRC(element), FALSE); +static GstElementStateReturn gst_httpsrc_change_state(GstElement *element) { + g_return_val_if_fail(GST_IS_HTTPSRC(element),GST_STATE_FAILURE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_httpsrc_open_url(GST_HTTPSRC(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_HTTPSRC_OPEN)) gst_httpsrc_close_url(GST_HTTPSRC(element)); - break; - default: - break; + } else { + if (!GST_FLAG_IS_SET(element,GST_HTTPSRC_OPEN)) { + if (!gst_httpsrc_open_url(GST_HTTPSRC(element))) + return GST_STATE_FAILURE; + } } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); - return TRUE; + return GST_ELEMENT_CLASS(parent_class)->change_state(element); + return GST_STATE_SUCCESS; } - diff --git a/plugins/elements/gsthttpsrc.h b/plugins/elements/gsthttpsrc.h index ae55f293f2..cd395cc76c 100644 --- a/plugins/elements/gsthttpsrc.h +++ b/plugins/elements/gsthttpsrc.h @@ -47,6 +47,11 @@ GstElementDetails gst_httpsrc_details; #define GST_IS_HTTPSRC_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_HTTPSRC))) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_HTTPSRC_OPEN = (1 << 16), +} GstHttpSrcFlags; + typedef struct _GstHttpSrc GstHttpSrc; typedef struct _GstHttpSrcClass GstHttpSrcClass; diff --git a/plugins/elements/gstpipefilter.c b/plugins/elements/gstpipefilter.c index 64b4dbb02f..d5bbaf6d21 100644 --- a/plugins/elements/gstpipefilter.c +++ b/plugins/elements/gstpipefilter.c @@ -59,8 +59,7 @@ static void gst_pipefilter_get_arg(GtkObject *object,GtkArg *arg,guint id); void gst_pipefilter_chain(GstPad *pad,GstBuffer *buf); -static gboolean gst_pipefilter_change_state(GstElement *element, - GstElementState state); +static GstElementStateReturn gst_pipefilter_change_state(GstElement *element); static GstFilterClass *parent_class = NULL; //static guint gst_pipefilter_signals[LAST_SIGNAL] = { 0 }; @@ -287,23 +286,22 @@ static void gst_pipefilter_close_file(GstPipefilter *src) { GST_FLAG_UNSET(src,GST_PIPEFILTER_OPEN); } -static gboolean gst_pipefilter_change_state(GstElement *element, - GstElementState state) { +static GstElementStateReturn gst_pipefilter_change_state(GstElement *element) { g_return_val_if_fail(GST_IS_PIPEFILTER(element), FALSE); - switch (state) { - case GST_STATE_RUNNING: - if (!gst_pipefilter_open_file(GST_PIPEFILTER(element))) - return FALSE; - break; - case ~GST_STATE_RUNNING: + /* if going down into NULL state, close the file if it's open */ + if (GST_STATE_PENDING(element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET(element,GST_PIPEFILTER_OPEN)) gst_pipefilter_close_file(GST_PIPEFILTER(element)); - break; - default: - break; - } + /* otherwise (READY or higher) we need to open the file */ + } else { + if (!GST_FLAG_IS_SET(element,GST_PIPEFILTER_OPEN)) { + if (!gst_disksrc_open_file(GST_PIPEFILTER(element))) + return GST_STATE_FAILURE; + } + } if (GST_ELEMENT_CLASS(parent_class)->change_state) - return GST_ELEMENT_CLASS(parent_class)->change_state(element,state); + return GST_ELEMENT_CLASS(parent_class)->change_state(element); return TRUE; } diff --git a/plugins/elements/gstpipefilter.h b/plugins/elements/gstpipefilter.h index 5243643e80..edd1d759a3 100644 --- a/plugins/elements/gstpipefilter.h +++ b/plugins/elements/gstpipefilter.h @@ -33,11 +33,6 @@ extern "C" { GstElementDetails gst_pipefilter_details; -// NOTE: per-element flags start with 16 for now -typedef enum { - GST_PIPEFILTER_OPEN = (1 << 16), -} GstPipefilterFlags; - #define GST_TYPE_PIPEFILTER \ (gst_pipefilter_get_type()) #define GST_PIPEFILTER(obj) \ @@ -49,6 +44,11 @@ typedef enum { #define GST_IS_PIPEFILTER_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_PIPEFILTER)) +// NOTE: per-element flags start with 16 for now +typedef enum { + GST_PIPEFILTER_OPEN = (1 << 16 ), +} GstPipeFilterFlags; + typedef struct _GstPipefilter GstPipefilter; typedef struct _GstPipefilterClass GstPipefilterClass;