I don't know how I ever got to introducing this madness, but I was wrong. *REALLY...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sun, 1 Jun 2003 12:27:39 +0000 (12:27 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sun, 1 Jun 2003 12:27:39 +0000 (12:27 +0000)
Original commit message from CVS:
I don't know how I ever got to introducing this madness, but I was wrong. *REALLY* wrong. It hasn't even worked, it still doesn't work and it will never work because the whole concept of doing a multifile output in filesink is completely braindead. Signal EOS, close file, set new filename and reset to PLAYING is so much easier. This patch removes all the multifile output cruft that I introduced and makes filesink simply work.

gst/elements/gstfilesink.c
gst/elements/gstfilesink.h
plugins/elements/gstfilesink.c
plugins/elements/gstfilesink.h

index 90dcfba..5c40021 100644 (file)
@@ -46,8 +46,7 @@ enum {
 
 enum {
   ARG_0,
-  ARG_LOCATION,
-  ARG_MAXFILESIZE,
+  ARG_LOCATION
 };
 
 GST_PAD_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
@@ -56,8 +55,16 @@ GST_PAD_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
                     GST_SEEK_METHOD_END |
                     GST_SEEK_FLAG_FLUSH },
   { GST_EVENT_FLUSH, 0 },
-  { GST_EVENT_DISCONTINUOUS, 0 },
-  { GST_EVENT_NEW_MEDIA, 0 }
+  { GST_EVENT_DISCONTINUOUS, 0 }
+)
+
+GST_PAD_QUERY_TYPE_FUNCTION (gst_filesink_get_query_types,
+  GST_QUERY_TOTAL,
+  GST_QUERY_POSITION
+)
+
+GST_PAD_FORMATS_FUNCTION (gst_filesink_get_formats,
+  GST_FORMAT_BYTES
 )
 
 
@@ -73,6 +80,8 @@ static gboolean gst_filesink_open_file                (GstFileSink *sink);
 static void    gst_filesink_close_file         (GstFileSink *sink);
 
 static gboolean gst_filesink_handle_event       (GstPad *pad, GstEvent *event);
+static gboolean        gst_filesink_pad_query          (GstPad *pad, GstQueryType type,
+                                                GstFormat *format, gint64 *value);
 static void    gst_filesink_chain              (GstPad *pad,GstBuffer *buf);
 
 static GstElementStateReturn gst_filesink_change_state (GstElement *element);
@@ -115,9 +124,6 @@ gst_filesink_class_init (GstFileSinkClass *klass)
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATION,
     g_param_spec_string ("location", "File Location", "Location of the file to write",
                          NULL, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAXFILESIZE,
-    g_param_spec_int ("maxfilesize", "MaxFileSize", "Maximum Size Per File in MB (-1 == no limit)",
-                     -1, G_MAXINT, -1, G_PARAM_READWRITE));
 
   gst_filesink_signals[SIGNAL_HANDOFF] =
     g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
@@ -143,30 +149,12 @@ gst_filesink_init (GstFileSink *filesink)
   gst_pad_set_event_function(pad, gst_filesink_handle_event);
   gst_pad_set_event_mask_function(pad, gst_filesink_get_event_mask);
 
+  gst_pad_set_query_function (pad, gst_filesink_pad_query);
+  gst_pad_set_query_type_function (pad, gst_filesink_get_query_types);
+  gst_pad_set_formats_function (pad, gst_filesink_get_formats);
+
   filesink->filename = NULL;
   filesink->file = NULL;
-  filesink->filenum = 0;
-
-  filesink->maxfilesize = -1;
-}
-
-static char *
-gst_filesink_getcurrentfilename (GstFileSink *filesink)
-{
-  g_return_val_if_fail(filesink != NULL, NULL);
-  g_return_val_if_fail(GST_IS_FILESINK(filesink), NULL);
-  if (filesink->filename == NULL) return NULL;
-  g_return_val_if_fail(filesink->filenum >= 0, NULL);
-
-  if (!strstr(filesink->filename, "%"))
-  {
-    if (!filesink->filenum)
-      return g_strdup(filesink->filename);
-    else
-      return NULL;
-  }
-
-  return g_strdup_printf(filesink->filename, filesink->filenum);
 }
 
 static void
@@ -180,23 +168,18 @@ gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value,
   switch (prop_id) {
     case ARG_LOCATION:
       /* the element must be stopped or paused in order to do this */
-      g_return_if_fail ((GST_STATE (sink) < GST_STATE_PLAYING)
-                      || (GST_STATE (sink) == GST_STATE_PAUSED));
+      g_return_if_fail (GST_STATE (sink) < GST_STATE_PLAYING);
       if (sink->filename)
        g_free (sink->filename);
       sink->filename = g_strdup (g_value_get_string (value));
-      if ( (GST_STATE (sink) == GST_STATE_PAUSED) 
-        && (sink->filename != NULL))
-      {
-              gst_filesink_close_file (sink);
-              gst_filesink_open_file (sink);   
+      if ((GST_STATE (sink) == GST_STATE_PAUSED) && 
+          (sink->filename != NULL)) {
+        gst_filesink_close_file (sink);
+        gst_filesink_open_file (sink);   
       }
-      break;
-    case ARG_MAXFILESIZE:
-      sink->maxfilesize = g_value_get_int(value);
       break;
     default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
@@ -213,10 +196,7 @@ gst_filesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
   
   switch (prop_id) {
     case ARG_LOCATION:
-      g_value_set_string (value, gst_filesink_getcurrentfilename(sink));
-      break;
-    case ARG_MAXFILESIZE:
-      g_value_set_int (value, sink->maxfilesize);
+      g_value_set_string (value, sink->filename);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -230,16 +210,17 @@ gst_filesink_open_file (GstFileSink *sink)
   g_return_val_if_fail (!GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN), FALSE);
 
   /* open the file */
-  if (!gst_filesink_getcurrentfilename(sink))
+  if (!sink->filename)
   {
     /* Out of files */
     return FALSE;
   }
-  sink->file = fopen (gst_filesink_getcurrentfilename(sink), "w");
+
+  sink->file = fopen (sink->filename, "w");
   if (sink->file == NULL) {
-    perror ("open");
-    gst_element_error (GST_ELEMENT (sink), g_strconcat("Error opening file \"",
-      gst_filesink_getcurrentfilename(sink), "\": ", g_strerror(errno), NULL));
+    gst_element_error (GST_ELEMENT (sink),
+                      "Error opening file %s: %s",
+                      sink->filename, g_strerror(errno));
     return FALSE;
   } 
 
@@ -257,15 +238,52 @@ gst_filesink_close_file (GstFileSink *sink)
 
   if (fclose (sink->file) != 0)
   {
-    perror ("close");
-    gst_element_error (GST_ELEMENT (sink), g_strconcat("Error closing file \"",
-      gst_filesink_getcurrentfilename(sink), "\": ", g_strerror(errno), NULL));
+    gst_element_error (GST_ELEMENT (sink),
+                      "Error closing file %s: %s",
+                      sink->filename, g_strerror(errno));
   }
   else {
     GST_FLAG_UNSET (sink, GST_FILESINK_OPEN);
   }
 }
 
+static gboolean
+gst_filesink_pad_query (GstPad *pad, GstQueryType type,
+                       GstFormat *format, gint64 *value)
+{
+  GstFileSink *sink = GST_FILESINK (GST_PAD_PARENT (pad));
+
+  switch (type) {
+    case GST_QUERY_TOTAL:
+      switch (*format) {
+       case GST_FORMAT_BYTES:
+          if (GST_FLAG_IS_SET (GST_ELEMENT(sink), GST_FILESINK_OPEN)) {
+            *value = sink->data_written; /* FIXME - doesn't the kernel provide
+                                           such a function? */
+            break;
+          }
+        default:
+         return FALSE;
+      }
+      break;
+    case GST_QUERY_POSITION:
+      switch (*format) {
+       case GST_FORMAT_BYTES:
+          if (GST_FLAG_IS_SET (GST_ELEMENT(sink), GST_FILESINK_OPEN)) {
+            *value = ftell (sink->file);
+            break;
+          }
+        default:
+         return FALSE;
+      }
+      break;
+    default:
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
 /* handle events (search) */
 static gboolean
 gst_filesink_handle_event (GstPad *pad, GstEvent *event)
@@ -275,31 +293,32 @@ gst_filesink_handle_event (GstPad *pad, GstEvent *event)
 
   filesink = GST_FILESINK (gst_pad_get_parent (pad));
 
+  g_return_val_if_fail (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN),
+                       FALSE);
+
   type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
 
   switch (type) {
     case GST_EVENT_SEEK:
-      /* we need to seek */
-      if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH)
-        if (fflush(filesink->file))
-          gst_element_error(GST_ELEMENT(filesink),
-            "Error flushing the buffer cache of file \'%s\' to disk: %s",
-            gst_filesink_getcurrentfilename(filesink), g_strerror(errno));
+      g_return_val_if_fail (GST_EVENT_SEEK_FORMAT (event) == GST_FORMAT_BYTES,
+                           FALSE);
 
-      if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES) {
-        g_warning("Any other then byte-offset seeking is not supported!\n");
-      }
+      if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH)
+        if (fflush (filesink->file))
+          gst_element_error (GST_ELEMENT (filesink),
+                            "Error flushing file %s: %s",
+                            filesink->filename, g_strerror(errno));
 
       switch (GST_EVENT_SEEK_METHOD(event))
       {
         case GST_SEEK_METHOD_SET:
-          fseek(filesink->file, GST_EVENT_SEEK_OFFSET(event), SEEK_SET);
+          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_SET);
           break;
         case GST_SEEK_METHOD_CUR:
-          fseek(filesink->file, GST_EVENT_SEEK_OFFSET(event), SEEK_CUR);
+          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_CUR);
           break;
         case GST_SEEK_METHOD_END:
-          fseek(filesink->file, GST_EVENT_SEEK_OFFSET(event), SEEK_END);
+          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_END);
           break;
         default:
           g_warning("unkown seek method!\n");
@@ -311,26 +330,21 @@ gst_filesink_handle_event (GstPad *pad, GstEvent *event)
       gint64 offset;
       
       if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &offset))
-        fseek(filesink->file, offset, SEEK_SET);
+        fseek (filesink->file, offset, SEEK_SET);
 
       gst_event_unref (event);
       break;
     }
-    case GST_EVENT_NEW_MEDIA:
-      /* we need to open a new file! */
-      gst_filesink_close_file(filesink);
-      filesink->filenum++;
-      if (!gst_filesink_open_file(filesink)) {
-       /* no more files, give EOS */
-        gst_element_set_eos(GST_ELEMENT(filesink));
-       return FALSE;
+    case GST_EVENT_FLUSH:
+      if (fflush (filesink->file)) {
+        gst_element_error (GST_ELEMENT (filesink),
+                          "Error flushing file %s: %s",
+                          filesink->filename, g_strerror(errno));
       }
       break;
-    case GST_EVENT_FLUSH:
-      if (fflush(filesink->file))
-        gst_element_error(GST_ELEMENT(filesink),
-          "Error flushing the buffer cache of file \'%s\' to disk: %s",
-          gst_filesink_getcurrentfilename(filesink), g_strerror(errno));
+    case GST_EVENT_EOS:
+      gst_filesink_close_file (filesink);
+      gst_element_set_eos (GST_ELEMENT (filesink));
       break;
     default:
       gst_pad_event_default (pad, event);
@@ -365,34 +379,23 @@ gst_filesink_chain (GstPad *pad, GstBuffer *buf)
     return;
   }
 
-  if (filesink->maxfilesize > 0)
-  {
-    if ((filesink->data_written + GST_BUFFER_SIZE(buf))/(1024*1024) > filesink->maxfilesize)
-    {
-      if (GST_ELEMENT_IS_EVENT_AWARE(GST_ELEMENT(filesink)))
-      {
-        GstEvent *event;
-        event = gst_event_new(GST_EVENT_NEW_MEDIA);
-        gst_pad_send_event(pad, event);
-      }
-    }
-  }
-
   if (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN))
   {
-    bytes_written = fwrite (GST_BUFFER_DATA (buf), 1, GST_BUFFER_SIZE (buf), filesink->file);
+    bytes_written = fwrite (GST_BUFFER_DATA (buf), 1,
+                            GST_BUFFER_SIZE (buf), filesink->file);
     if (bytes_written < GST_BUFFER_SIZE (buf))
     {
-      printf ("filesink : Warning : %d bytes should be written, only %d bytes written\n",
+      g_warning ("filesink: %d bytes should be written, only %d bytes written\n",
                  GST_BUFFER_SIZE (buf), bytes_written);
     }
+    filesink->data_written += bytes_written;
   }
-  filesink->data_written += GST_BUFFER_SIZE(buf);
 
   gst_buffer_unref (buf);
 
-  g_signal_emit (G_OBJECT (filesink), gst_filesink_signals[SIGNAL_HANDOFF], 0,
-                             filesink);
+  g_signal_emit (G_OBJECT (filesink),
+                 gst_filesink_signals[SIGNAL_HANDOFF], 0,
+                filesink);
 }
 
 static GstElementStateReturn
@@ -400,14 +403,18 @@ gst_filesink_change_state (GstElement *element)
 {
   g_return_val_if_fail (GST_IS_FILESINK (element), GST_STATE_FAILURE);
 
-  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
-    if (GST_FLAG_IS_SET (element, GST_FILESINK_OPEN))
-      gst_filesink_close_file (GST_FILESINK (element));
-  } else {
-    if (!GST_FLAG_IS_SET (element, GST_FILESINK_OPEN)) {
-      if (!gst_filesink_open_file (GST_FILESINK (element)))
-        return GST_STATE_FAILURE;
-    }
+  switch (GST_STATE_TRANSITION (element)) {
+    case GST_STATE_PAUSED_TO_READY:
+      if (GST_FLAG_IS_SET (element, GST_FILESINK_OPEN))
+        gst_filesink_close_file (GST_FILESINK (element));
+      break;
+
+    case GST_STATE_READY_TO_PAUSED:
+      if (!GST_FLAG_IS_SET (element, GST_FILESINK_OPEN)) {
+        if (!gst_filesink_open_file (GST_FILESINK (element)))
+          return GST_STATE_FAILURE;
+      }
+      break;
   }
 
   if (GST_ELEMENT_CLASS (parent_class)->change_state)
@@ -415,4 +422,3 @@ gst_filesink_change_state (GstElement *element)
 
   return GST_STATE_SUCCESS;
 }
-
index b9da688..d9ffa5b 100644 (file)
@@ -59,17 +59,14 @@ struct _GstFileSink {
   gchar *filename;
   FILE *file;
 
-  gint filenum;
-
   guint64 data_written;
-  gint maxfilesize;
 };
 
 struct _GstFileSinkClass {
   GstElementClass parent_class;
 
   /* signals */
-  void (*handoff) (GstElement *element,GstPad *pad);
+  void (*handoff) (GstElement *element, GstPad *pad);
 };
 
 GType gst_filesink_get_type(void);
index 90dcfba..5c40021 100644 (file)
@@ -46,8 +46,7 @@ enum {
 
 enum {
   ARG_0,
-  ARG_LOCATION,
-  ARG_MAXFILESIZE,
+  ARG_LOCATION
 };
 
 GST_PAD_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
@@ -56,8 +55,16 @@ GST_PAD_EVENT_MASK_FUNCTION (gst_filesink_get_event_mask,
                     GST_SEEK_METHOD_END |
                     GST_SEEK_FLAG_FLUSH },
   { GST_EVENT_FLUSH, 0 },
-  { GST_EVENT_DISCONTINUOUS, 0 },
-  { GST_EVENT_NEW_MEDIA, 0 }
+  { GST_EVENT_DISCONTINUOUS, 0 }
+)
+
+GST_PAD_QUERY_TYPE_FUNCTION (gst_filesink_get_query_types,
+  GST_QUERY_TOTAL,
+  GST_QUERY_POSITION
+)
+
+GST_PAD_FORMATS_FUNCTION (gst_filesink_get_formats,
+  GST_FORMAT_BYTES
 )
 
 
@@ -73,6 +80,8 @@ static gboolean gst_filesink_open_file                (GstFileSink *sink);
 static void    gst_filesink_close_file         (GstFileSink *sink);
 
 static gboolean gst_filesink_handle_event       (GstPad *pad, GstEvent *event);
+static gboolean        gst_filesink_pad_query          (GstPad *pad, GstQueryType type,
+                                                GstFormat *format, gint64 *value);
 static void    gst_filesink_chain              (GstPad *pad,GstBuffer *buf);
 
 static GstElementStateReturn gst_filesink_change_state (GstElement *element);
@@ -115,9 +124,6 @@ gst_filesink_class_init (GstFileSinkClass *klass)
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOCATION,
     g_param_spec_string ("location", "File Location", "Location of the file to write",
                          NULL, G_PARAM_READWRITE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAXFILESIZE,
-    g_param_spec_int ("maxfilesize", "MaxFileSize", "Maximum Size Per File in MB (-1 == no limit)",
-                     -1, G_MAXINT, -1, G_PARAM_READWRITE));
 
   gst_filesink_signals[SIGNAL_HANDOFF] =
     g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
@@ -143,30 +149,12 @@ gst_filesink_init (GstFileSink *filesink)
   gst_pad_set_event_function(pad, gst_filesink_handle_event);
   gst_pad_set_event_mask_function(pad, gst_filesink_get_event_mask);
 
+  gst_pad_set_query_function (pad, gst_filesink_pad_query);
+  gst_pad_set_query_type_function (pad, gst_filesink_get_query_types);
+  gst_pad_set_formats_function (pad, gst_filesink_get_formats);
+
   filesink->filename = NULL;
   filesink->file = NULL;
-  filesink->filenum = 0;
-
-  filesink->maxfilesize = -1;
-}
-
-static char *
-gst_filesink_getcurrentfilename (GstFileSink *filesink)
-{
-  g_return_val_if_fail(filesink != NULL, NULL);
-  g_return_val_if_fail(GST_IS_FILESINK(filesink), NULL);
-  if (filesink->filename == NULL) return NULL;
-  g_return_val_if_fail(filesink->filenum >= 0, NULL);
-
-  if (!strstr(filesink->filename, "%"))
-  {
-    if (!filesink->filenum)
-      return g_strdup(filesink->filename);
-    else
-      return NULL;
-  }
-
-  return g_strdup_printf(filesink->filename, filesink->filenum);
 }
 
 static void
@@ -180,23 +168,18 @@ gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value,
   switch (prop_id) {
     case ARG_LOCATION:
       /* the element must be stopped or paused in order to do this */
-      g_return_if_fail ((GST_STATE (sink) < GST_STATE_PLAYING)
-                      || (GST_STATE (sink) == GST_STATE_PAUSED));
+      g_return_if_fail (GST_STATE (sink) < GST_STATE_PLAYING);
       if (sink->filename)
        g_free (sink->filename);
       sink->filename = g_strdup (g_value_get_string (value));
-      if ( (GST_STATE (sink) == GST_STATE_PAUSED) 
-        && (sink->filename != NULL))
-      {
-              gst_filesink_close_file (sink);
-              gst_filesink_open_file (sink);   
+      if ((GST_STATE (sink) == GST_STATE_PAUSED) && 
+          (sink->filename != NULL)) {
+        gst_filesink_close_file (sink);
+        gst_filesink_open_file (sink);   
       }
-      break;
-    case ARG_MAXFILESIZE:
-      sink->maxfilesize = g_value_get_int(value);
       break;
     default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
@@ -213,10 +196,7 @@ gst_filesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
   
   switch (prop_id) {
     case ARG_LOCATION:
-      g_value_set_string (value, gst_filesink_getcurrentfilename(sink));
-      break;
-    case ARG_MAXFILESIZE:
-      g_value_set_int (value, sink->maxfilesize);
+      g_value_set_string (value, sink->filename);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -230,16 +210,17 @@ gst_filesink_open_file (GstFileSink *sink)
   g_return_val_if_fail (!GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN), FALSE);
 
   /* open the file */
-  if (!gst_filesink_getcurrentfilename(sink))
+  if (!sink->filename)
   {
     /* Out of files */
     return FALSE;
   }
-  sink->file = fopen (gst_filesink_getcurrentfilename(sink), "w");
+
+  sink->file = fopen (sink->filename, "w");
   if (sink->file == NULL) {
-    perror ("open");
-    gst_element_error (GST_ELEMENT (sink), g_strconcat("Error opening file \"",
-      gst_filesink_getcurrentfilename(sink), "\": ", g_strerror(errno), NULL));
+    gst_element_error (GST_ELEMENT (sink),
+                      "Error opening file %s: %s",
+                      sink->filename, g_strerror(errno));
     return FALSE;
   } 
 
@@ -257,15 +238,52 @@ gst_filesink_close_file (GstFileSink *sink)
 
   if (fclose (sink->file) != 0)
   {
-    perror ("close");
-    gst_element_error (GST_ELEMENT (sink), g_strconcat("Error closing file \"",
-      gst_filesink_getcurrentfilename(sink), "\": ", g_strerror(errno), NULL));
+    gst_element_error (GST_ELEMENT (sink),
+                      "Error closing file %s: %s",
+                      sink->filename, g_strerror(errno));
   }
   else {
     GST_FLAG_UNSET (sink, GST_FILESINK_OPEN);
   }
 }
 
+static gboolean
+gst_filesink_pad_query (GstPad *pad, GstQueryType type,
+                       GstFormat *format, gint64 *value)
+{
+  GstFileSink *sink = GST_FILESINK (GST_PAD_PARENT (pad));
+
+  switch (type) {
+    case GST_QUERY_TOTAL:
+      switch (*format) {
+       case GST_FORMAT_BYTES:
+          if (GST_FLAG_IS_SET (GST_ELEMENT(sink), GST_FILESINK_OPEN)) {
+            *value = sink->data_written; /* FIXME - doesn't the kernel provide
+                                           such a function? */
+            break;
+          }
+        default:
+         return FALSE;
+      }
+      break;
+    case GST_QUERY_POSITION:
+      switch (*format) {
+       case GST_FORMAT_BYTES:
+          if (GST_FLAG_IS_SET (GST_ELEMENT(sink), GST_FILESINK_OPEN)) {
+            *value = ftell (sink->file);
+            break;
+          }
+        default:
+         return FALSE;
+      }
+      break;
+    default:
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
 /* handle events (search) */
 static gboolean
 gst_filesink_handle_event (GstPad *pad, GstEvent *event)
@@ -275,31 +293,32 @@ gst_filesink_handle_event (GstPad *pad, GstEvent *event)
 
   filesink = GST_FILESINK (gst_pad_get_parent (pad));
 
+  g_return_val_if_fail (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN),
+                       FALSE);
+
   type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
 
   switch (type) {
     case GST_EVENT_SEEK:
-      /* we need to seek */
-      if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH)
-        if (fflush(filesink->file))
-          gst_element_error(GST_ELEMENT(filesink),
-            "Error flushing the buffer cache of file \'%s\' to disk: %s",
-            gst_filesink_getcurrentfilename(filesink), g_strerror(errno));
+      g_return_val_if_fail (GST_EVENT_SEEK_FORMAT (event) == GST_FORMAT_BYTES,
+                           FALSE);
 
-      if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES) {
-        g_warning("Any other then byte-offset seeking is not supported!\n");
-      }
+      if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH)
+        if (fflush (filesink->file))
+          gst_element_error (GST_ELEMENT (filesink),
+                            "Error flushing file %s: %s",
+                            filesink->filename, g_strerror(errno));
 
       switch (GST_EVENT_SEEK_METHOD(event))
       {
         case GST_SEEK_METHOD_SET:
-          fseek(filesink->file, GST_EVENT_SEEK_OFFSET(event), SEEK_SET);
+          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_SET);
           break;
         case GST_SEEK_METHOD_CUR:
-          fseek(filesink->file, GST_EVENT_SEEK_OFFSET(event), SEEK_CUR);
+          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_CUR);
           break;
         case GST_SEEK_METHOD_END:
-          fseek(filesink->file, GST_EVENT_SEEK_OFFSET(event), SEEK_END);
+          fseek (filesink->file, GST_EVENT_SEEK_OFFSET (event), SEEK_END);
           break;
         default:
           g_warning("unkown seek method!\n");
@@ -311,26 +330,21 @@ gst_filesink_handle_event (GstPad *pad, GstEvent *event)
       gint64 offset;
       
       if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &offset))
-        fseek(filesink->file, offset, SEEK_SET);
+        fseek (filesink->file, offset, SEEK_SET);
 
       gst_event_unref (event);
       break;
     }
-    case GST_EVENT_NEW_MEDIA:
-      /* we need to open a new file! */
-      gst_filesink_close_file(filesink);
-      filesink->filenum++;
-      if (!gst_filesink_open_file(filesink)) {
-       /* no more files, give EOS */
-        gst_element_set_eos(GST_ELEMENT(filesink));
-       return FALSE;
+    case GST_EVENT_FLUSH:
+      if (fflush (filesink->file)) {
+        gst_element_error (GST_ELEMENT (filesink),
+                          "Error flushing file %s: %s",
+                          filesink->filename, g_strerror(errno));
       }
       break;
-    case GST_EVENT_FLUSH:
-      if (fflush(filesink->file))
-        gst_element_error(GST_ELEMENT(filesink),
-          "Error flushing the buffer cache of file \'%s\' to disk: %s",
-          gst_filesink_getcurrentfilename(filesink), g_strerror(errno));
+    case GST_EVENT_EOS:
+      gst_filesink_close_file (filesink);
+      gst_element_set_eos (GST_ELEMENT (filesink));
       break;
     default:
       gst_pad_event_default (pad, event);
@@ -365,34 +379,23 @@ gst_filesink_chain (GstPad *pad, GstBuffer *buf)
     return;
   }
 
-  if (filesink->maxfilesize > 0)
-  {
-    if ((filesink->data_written + GST_BUFFER_SIZE(buf))/(1024*1024) > filesink->maxfilesize)
-    {
-      if (GST_ELEMENT_IS_EVENT_AWARE(GST_ELEMENT(filesink)))
-      {
-        GstEvent *event;
-        event = gst_event_new(GST_EVENT_NEW_MEDIA);
-        gst_pad_send_event(pad, event);
-      }
-    }
-  }
-
   if (GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN))
   {
-    bytes_written = fwrite (GST_BUFFER_DATA (buf), 1, GST_BUFFER_SIZE (buf), filesink->file);
+    bytes_written = fwrite (GST_BUFFER_DATA (buf), 1,
+                            GST_BUFFER_SIZE (buf), filesink->file);
     if (bytes_written < GST_BUFFER_SIZE (buf))
     {
-      printf ("filesink : Warning : %d bytes should be written, only %d bytes written\n",
+      g_warning ("filesink: %d bytes should be written, only %d bytes written\n",
                  GST_BUFFER_SIZE (buf), bytes_written);
     }
+    filesink->data_written += bytes_written;
   }
-  filesink->data_written += GST_BUFFER_SIZE(buf);
 
   gst_buffer_unref (buf);
 
-  g_signal_emit (G_OBJECT (filesink), gst_filesink_signals[SIGNAL_HANDOFF], 0,
-                             filesink);
+  g_signal_emit (G_OBJECT (filesink),
+                 gst_filesink_signals[SIGNAL_HANDOFF], 0,
+                filesink);
 }
 
 static GstElementStateReturn
@@ -400,14 +403,18 @@ gst_filesink_change_state (GstElement *element)
 {
   g_return_val_if_fail (GST_IS_FILESINK (element), GST_STATE_FAILURE);
 
-  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
-    if (GST_FLAG_IS_SET (element, GST_FILESINK_OPEN))
-      gst_filesink_close_file (GST_FILESINK (element));
-  } else {
-    if (!GST_FLAG_IS_SET (element, GST_FILESINK_OPEN)) {
-      if (!gst_filesink_open_file (GST_FILESINK (element)))
-        return GST_STATE_FAILURE;
-    }
+  switch (GST_STATE_TRANSITION (element)) {
+    case GST_STATE_PAUSED_TO_READY:
+      if (GST_FLAG_IS_SET (element, GST_FILESINK_OPEN))
+        gst_filesink_close_file (GST_FILESINK (element));
+      break;
+
+    case GST_STATE_READY_TO_PAUSED:
+      if (!GST_FLAG_IS_SET (element, GST_FILESINK_OPEN)) {
+        if (!gst_filesink_open_file (GST_FILESINK (element)))
+          return GST_STATE_FAILURE;
+      }
+      break;
   }
 
   if (GST_ELEMENT_CLASS (parent_class)->change_state)
@@ -415,4 +422,3 @@ gst_filesink_change_state (GstElement *element)
 
   return GST_STATE_SUCCESS;
 }
-
index b9da688..d9ffa5b 100644 (file)
@@ -59,17 +59,14 @@ struct _GstFileSink {
   gchar *filename;
   FILE *file;
 
-  gint filenum;
-
   guint64 data_written;
-  gint maxfilesize;
 };
 
 struct _GstFileSinkClass {
   GstElementClass parent_class;
 
   /* signals */
-  void (*handoff) (GstElement *element,GstPad *pad);
+  void (*handoff) (GstElement *element, GstPad *pad);
 };
 
 GType gst_filesink_get_type(void);