From 49a4b801ac8490731afbfbc176f8bf2adb0f1954 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 10 Apr 2012 11:16:14 +0200 Subject: [PATCH 1/4] queue2: make range on newsegment for ringbuffer When using the ringbuffer, handle the newsegment event like we handle it when using the temp-file mode: create a new range for the new byte segment. The new segment should normally already be created when we do a seek. --- plugins/elements/gstqueue2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index 77f68d94f6..548d99ac52 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -740,7 +740,7 @@ apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment, G_GINT64_FORMAT, update, rate, arate, format, start, stop, time); if (format == GST_FORMAT_BYTES) { - if (QUEUE_IS_USING_TEMP_FILE (queue)) { + if (!QUEUE_IS_USING_QUEUE (queue)) { /* start is where we'll be getting from and as such writing next */ queue->current = add_range (queue, start); /* update the stats for this range */ From 5755e2437919a3c5f4998fa1336dc7c96da5a020 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 10 Apr 2012 11:20:09 +0200 Subject: [PATCH 2/4] queue2: Keep track of the seeking state Set the seeking flag right before we send a seek event upstream and discard all data untill we see a flush-stop again. We need to do this because we activate the range that we seek to immediately after sending the seek event and it is possible that we receive data in our chain function from before the seek which would then be added to the wrong range resulting in data corruption. --- plugins/elements/gstqueue2.c | 15 +++++++++++++++ plugins/elements/gstqueue2.h | 1 + 2 files changed, 16 insertions(+) diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index 548d99ac52..ab725b5099 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -1096,6 +1096,8 @@ perform_seek_to_offset (GstQueue2 * queue, guint64 offset) GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1); + /* until we receive the FLUSH_STOP from this seek, we skip data */ + queue->seeking = TRUE; res = gst_pad_push_event (queue->sinkpad, event); GST_QUEUE2_MUTEX_LOCK (queue); @@ -2181,6 +2183,7 @@ gst_queue2_handle_sink_event (GstPad * pad, GstEvent * event) queue->sinkresult = GST_FLOW_OK; queue->is_eos = FALSE; queue->unexpected = FALSE; + queue->seeking = FALSE; /* reset rate counters */ reset_rate_timer (queue); gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue2_loop, @@ -2307,6 +2310,10 @@ gst_queue2_chain_buffer_or_buffer_list (GstQueue2 * queue, if (queue->unexpected) goto out_unexpected; + /* while we didn't receive the newsegment, we're seeking and we skip data */ + if (queue->seeking) + goto out_seeking; + if (!gst_queue2_wait_free_space (queue)) goto out_flushing; @@ -2336,6 +2343,14 @@ out_eos: return GST_FLOW_UNEXPECTED; } +out_seeking: + { + GST_CAT_LOG_OBJECT (queue_dataflow, queue, "exit because we are seeking"); + GST_QUEUE2_MUTEX_UNLOCK (queue); + gst_mini_object_unref (item); + + return GST_FLOW_OK; + } out_unexpected: { GST_CAT_LOG_OBJECT (queue_dataflow, queue, diff --git a/plugins/elements/gstqueue2.h b/plugins/elements/gstqueue2.h index 02a38f264a..3698344e26 100644 --- a/plugins/elements/gstqueue2.h +++ b/plugins/elements/gstqueue2.h @@ -143,6 +143,7 @@ struct _GstQueue2 * because we can't save it on the file */ gboolean segment_event_received; GstEvent *starting_segment; + gboolean seeking; guint64 ring_buffer_max_size; guint8 * ring_buffer; From b7a8051d95ae9dbf3aaef2faacf66e753717ba9f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 10 Apr 2012 12:09:53 +0200 Subject: [PATCH 3/4] queue2: set seeking flag with the queue lock --- plugins/elements/gstqueue2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index ab725b5099..35e5e1eb9c 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -1087,6 +1087,8 @@ perform_seek_to_offset (GstQueue2 * queue, guint64 offset) GstEvent *event; gboolean res; + /* until we receive the FLUSH_STOP from this seek, we skip data */ + queue->seeking = TRUE; GST_QUEUE2_MUTEX_UNLOCK (queue); GST_DEBUG_OBJECT (queue, "Seeking to %" G_GUINT64_FORMAT, offset); @@ -1096,8 +1098,6 @@ perform_seek_to_offset (GstQueue2 * queue, guint64 offset) GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset, GST_SEEK_TYPE_NONE, -1); - /* until we receive the FLUSH_STOP from this seek, we skip data */ - queue->seeking = TRUE; res = gst_pad_push_event (queue->sinkpad, event); GST_QUEUE2_MUTEX_LOCK (queue); From fd9c328260556b96039d681c4083d079ff1756c7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 10 Apr 2012 12:49:04 +0200 Subject: [PATCH 4/4] gst: add toc entry ref/unref --- gst/gst.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/gst.c b/gst/gst.c index 8582650903..4875b13f29 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -756,6 +756,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data, g_type_class_ref (gst_search_mode_get_type ()); g_type_class_ref (gst_progress_type_get_type ()); g_type_class_ref (gst_caps_intersect_mode_get_type ()); + g_type_class_ref (gst_toc_entry_type_get_type ()); gst_structure_get_type (); _gst_value_initialize (); @@ -1125,6 +1126,7 @@ gst_deinit (void) g_type_class_unref (g_type_class_peek (gst_param_spec_fraction_get_type ())); g_type_class_unref (g_type_class_peek (gst_progress_type_get_type ())); g_type_class_unref (g_type_class_peek (gst_caps_intersect_mode_get_type ())); + g_type_class_unref (g_type_class_peek (gst_toc_entry_type_get_type ())); gst_deinitialized = TRUE; GST_INFO ("deinitialized GStreamer");