Brought standard elements in line with new state management system.
authorErik Walthinsen <omega@temple-baptist.org>
Fri, 21 Jul 2000 03:57:51 +0000 (03:57 +0000)
committerErik Walthinsen <omega@temple-baptist.org>
Fri, 21 Jul 2000 03:57:51 +0000 (03:57 +0000)
Original commit message from CVS:
Brought standard elements in line with new state management system.

24 files changed:
gst/elements/gstasyncdisksrc.c
gst/elements/gstaudiosink.c
gst/elements/gstaudiosink.h
gst/elements/gstaudiosrc.c
gst/elements/gstaudiosrc.h
gst/elements/gstdisksrc.c
gst/elements/gstdisksrc.h
gst/elements/gstfdsrc.c
gst/elements/gsthttpsrc.c
gst/elements/gsthttpsrc.h
gst/elements/gstpipefilter.c
gst/elements/gstpipefilter.h
plugins/elements/gstasyncdisksrc.c
plugins/elements/gstaudiosink.c
plugins/elements/gstaudiosink.h
plugins/elements/gstaudiosrc.c
plugins/elements/gstaudiosrc.h
plugins/elements/gstdisksrc.c
plugins/elements/gstdisksrc.h
plugins/elements/gstfdsrc.c
plugins/elements/gsthttpsrc.c
plugins/elements/gsthttpsrc.h
plugins/elements/gstpipefilter.c
plugins/elements/gstpipefilter.h

index 1d534a4..9443db0 100644 (file)
@@ -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;
 }
index be54778..30da25f 100644 (file)
@@ -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) {
-  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) {
+static GstElementStateReturn gst_audiosink_change_state(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;
 }
index 26a1041..45ffa1f 100644 (file)
@@ -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;
 
index 670657f..38ad86f 100644 (file)
@@ -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) {
index bd2a9c6..de595b2 100644 (file)
@@ -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;
 
index 5e852f8..0484a09 100644 (file)
@@ -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;
 }
index 95c66b3..26afb42 100644 (file)
@@ -58,9 +58,8 @@ struct _GstDiskSrc {
   /* pads */
   GstPad *srcpad;
 
-  /* filename */
+  /* file state */
   gchar *filename;
-  /* fd */
   gint fd;
 
   gulong curoffset;                    /* current offset in file */
index 085f755..e88b9c5 100644 (file)
@@ -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:
index 094ed07..725b805 100644 (file)
@@ -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;
 }
-
index ae55f29..cd395cc 100644 (file)
@@ -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;
 
index 64b4dbb..d5bbaf6 100644 (file)
@@ -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;
 }
index 5243643..edd1d75 100644 (file)
@@ -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;
 
index 1d534a4..9443db0 100644 (file)
@@ -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;
 }
index be54778..30da25f 100644 (file)
@@ -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) {
-  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) {
+static GstElementStateReturn gst_audiosink_change_state(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;
 }
index 26a1041..45ffa1f 100644 (file)
@@ -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;
 
index 670657f..38ad86f 100644 (file)
@@ -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) {
index bd2a9c6..de595b2 100644 (file)
@@ -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;
 
index 5e852f8..0484a09 100644 (file)
@@ -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;
 }
index 95c66b3..26afb42 100644 (file)
@@ -58,9 +58,8 @@ struct _GstDiskSrc {
   /* pads */
   GstPad *srcpad;
 
-  /* filename */
+  /* file state */
   gchar *filename;
-  /* fd */
   gint fd;
 
   gulong curoffset;                    /* current offset in file */
index 085f755..e88b9c5 100644 (file)
@@ -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:
index 094ed07..725b805 100644 (file)
@@ -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;
 }
-
index ae55f29..cd395cc 100644 (file)
@@ -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;
 
index 64b4dbb..d5bbaf6 100644 (file)
@@ -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;
 }
index 5243643..edd1d75 100644 (file)
@@ -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;