filesink: flush (discard data) on FLUSH_STOP
authorAlessandro Decina <alessandro.d@gmail.com>
Tue, 27 Aug 2013 05:51:35 +0000 (07:51 +0200)
committerAlessandro Decina <alessandro.d@gmail.com>
Tue, 27 Aug 2013 06:00:09 +0000 (08:00 +0200)
Reset the write position to 0 and truncate the file on FLUSH_STOP.

plugins/elements/gstfilesink.c
tests/check/elements/filesink.c

index 6700b13..b59d72f 100644 (file)
@@ -56,6 +56,8 @@
 #define lseek _lseeki64
 #undef off_t
 #define off_t guint64
+#undef ftruncate
+#define ftruncate _chsize
 #ifdef _MSC_VER                 /* Check if we are using MSVC, fileno is deprecated in favour */
 #define fileno _fileno          /* of _fileno */
 #endif
@@ -242,6 +244,7 @@ gst_file_sink_init (GstFileSink * filesink)
 {
   filesink->filename = NULL;
   filesink->file = NULL;
+  filesink->current_pos = 0;
   filesink->buffer_mode = DEFAULT_BUFFER_MODE;
   filesink->buffer_size = DEFAULT_BUFFER_SIZE;
   filesink->buffer = NULL;
@@ -584,6 +587,12 @@ gst_file_sink_event (GstBaseSink * sink, GstEvent * event)
       }
       break;
     }
+    case GST_EVENT_FLUSH_STOP:
+      if (filesink->current_pos != 0 && filesink->seekable) {
+        gst_file_sink_do_seek (filesink, 0);
+        ftruncate (fileno (filesink->file), 0);
+      }
+      break;
     case GST_EVENT_EOS:
       if (fflush (filesink->file))
         goto flush_failed;
index b79b108..afe06ee 100644 (file)
@@ -226,6 +226,56 @@ GST_START_TEST (test_seeking)
 
 GST_END_TEST;
 
+GST_START_TEST (test_flush)
+{
+  GstElement *filesink;
+  gchar *tmp_fn;
+  GstSegment segment;
+
+  tmp_fn = create_temporary_file ();
+  if (tmp_fn == NULL)
+    return;
+  filesink = setup_filesink ();
+
+  GST_LOG ("using temp file '%s'", tmp_fn);
+  g_object_set (filesink, "location", tmp_fn, NULL);
+
+  fail_unless_equals_int (gst_element_set_state (filesink, GST_STATE_PLAYING),
+      GST_STATE_CHANGE_ASYNC);
+
+  fail_unless (gst_pad_push_event (mysrcpad,
+          gst_event_new_stream_start ("test")));
+
+  gst_segment_init (&segment, GST_FORMAT_TIME);
+  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
+
+  CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 0);
+
+  PUSH_BYTES (8);
+  CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 8);
+
+  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_flush_start ()));
+  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_flush_stop (TRUE)));
+  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
+
+  fail_unless_equals_int (gst_element_set_state (filesink, GST_STATE_PLAYING),
+      GST_STATE_CHANGE_ASYNC);
+
+  CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 0);
+
+  PUSH_BYTES (4);
+  CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 4);
+
+  cleanup_filesink (filesink);
+
+  CHECK_WRITTEN_BYTES (0, 4, 4);
+
+  g_remove (tmp_fn);
+  g_free (tmp_fn);
+}
+
+GST_END_TEST;
+
 GST_START_TEST (test_coverage)
 {
   GstElement *filesink;
@@ -335,6 +385,7 @@ filesink_suite (void)
   tcase_add_test (tc_chain, test_coverage);
   tcase_add_test (tc_chain, test_uri_interface);
   tcase_add_test (tc_chain, test_seeking);
+  tcase_add_test (tc_chain, test_flush);
 
   return s;
 }