From 924acf5e9243496c4d9b7897e17c87b063f9e59d Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Tue, 27 Aug 2013 07:51:35 +0200 Subject: [PATCH] filesink: flush (discard data) on FLUSH_STOP Reset the write position to 0 and truncate the file on FLUSH_STOP. --- plugins/elements/gstfilesink.c | 9 ++++++ tests/check/elements/filesink.c | 51 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index 6700b13df7..b59d72fc62 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -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; diff --git a/tests/check/elements/filesink.c b/tests/check/elements/filesink.c index b79b10864d..afe06eef4c 100644 --- a/tests/check/elements/filesink.c +++ b/tests/check/elements/filesink.c @@ -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; }