freeze: Use a GPtrArray instead of a GQueue

This way, the most common function (changing buffers) becomes O(1) instead
of O(n)
This commit is contained in:
Olivier Crête 2012-09-12 17:34:03 -04:00
parent e23e3d6b64
commit bfb56f8380
2 changed files with 18 additions and 38 deletions

View file

@ -73,7 +73,6 @@ static gboolean gst_freeze_sink_activate_mode (GstPad * sinkpad,
static gboolean gst_freeze_sink_event (GstPad * pad, GstObject * parent, static gboolean gst_freeze_sink_event (GstPad * pad, GstObject * parent,
GstEvent * event); GstEvent * event);
static void gst_freeze_clear_buffer (GstFreeze * freeze); static void gst_freeze_clear_buffer (GstFreeze * freeze);
static void gst_freeze_buffer_free (gpointer data, gpointer user_data);
G_DEFINE_TYPE (GstFreeze, gst_freeze, GST_TYPE_ELEMENT); G_DEFINE_TYPE (GstFreeze, gst_freeze, GST_TYPE_ELEMENT);
@ -133,9 +132,10 @@ gst_freeze_init (GstFreeze * freeze)
freeze->timestamp_offset = 0; freeze->timestamp_offset = 0;
freeze->running_time = 0; freeze->running_time = 0;
freeze->current = NULL; freeze->current = 0;
freeze->max_buffers = 1; freeze->max_buffers = 1;
freeze->buffers = g_queue_new (); freeze->buffers = g_ptr_array_new_with_free_func (
(GDestroyNotify) gst_buffer_unref);
} }
static void static void
@ -144,8 +144,7 @@ gst_freeze_dispose (GObject * object)
GstFreeze *freeze = GST_FREEZE (object); GstFreeze *freeze = GST_FREEZE (object);
gst_freeze_clear_buffer (freeze); gst_freeze_clear_buffer (freeze);
g_ptr_array_free (freeze->buffers, TRUE);
g_queue_free (freeze->buffers);
G_OBJECT_CLASS (gst_freeze_parent_class)->dispose (object); G_OBJECT_CLASS (gst_freeze_parent_class)->dispose (object);
} }
@ -214,39 +213,28 @@ gst_freeze_play (GstFreeze * freeze, GstBuffer * buf)
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
GstBuffer *outbuf; GstBuffer *outbuf;
if (freeze->current == NULL) if (freeze->buffers->len == 0)
freeze->timestamp_offset = GST_BUFFER_TIMESTAMP (buf); freeze->timestamp_offset = GST_BUFFER_TIMESTAMP (buf);
if (g_queue_get_length (freeze->buffers) < freeze->max_buffers || if (freeze->buffers->len < freeze->max_buffers || freeze->max_buffers == 0) {
freeze->max_buffers == 0) { g_ptr_array_add (freeze->buffers, buf);
g_queue_push_tail (freeze->buffers, buf); GST_DEBUG_OBJECT (freeze, "accepted buffer %u", freeze->buffers->len - 1);
GST_DEBUG_OBJECT (freeze, "accepted buffer %u",
g_queue_get_length (freeze->buffers) - 1);
} else { } else {
gst_buffer_unref (buf); gst_buffer_unref (buf);
} }
outbuf =
if (freeze->current != NULL) { gst_buffer_copy (g_ptr_array_index (freeze->buffers, freeze->current));
GST_DEBUG_OBJECT (freeze, "switching to next buffer"); freeze->current++;
freeze->current = g_queue_peek_nth (freeze->buffers, freeze->current %= freeze->buffers->len;
g_queue_index (freeze->buffers, (gpointer) freeze->current) + 1);
}
if (freeze->current == NULL) {
if (freeze->max_buffers > 1)
GST_DEBUG_OBJECT (freeze, "restarting the loop");
freeze->current = g_queue_peek_head (freeze->buffers);
}
outbuf = gst_buffer_copy (freeze->current);
GST_BUFFER_TIMESTAMP (outbuf) = freeze->timestamp_offset + GST_BUFFER_TIMESTAMP (outbuf) = freeze->timestamp_offset +
freeze->running_time; freeze->running_time;
freeze->running_time += GST_BUFFER_DURATION (freeze->current); freeze->running_time += GST_BUFFER_DURATION (outbuf);
ret = gst_pad_push (freeze->srcpad, outbuf); ret = gst_pad_push (freeze->srcpad, outbuf);
return ret; return ret;
} }
@ -312,19 +300,11 @@ gst_freeze_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
return result; return result;
} }
static void
gst_freeze_buffer_free (gpointer data, gpointer user_data)
{
gst_buffer_unref (GST_BUFFER (data));
}
static void static void
gst_freeze_clear_buffer (GstFreeze * freeze) gst_freeze_clear_buffer (GstFreeze * freeze)
{ {
if (freeze->buffers != NULL) { g_ptr_array_set_size (freeze->buffers, 0);
g_queue_foreach (freeze->buffers, gst_freeze_buffer_free, NULL); freeze->current = 0;
}
freeze->current = NULL;
freeze->running_time = 0; freeze->running_time = 0;
} }

View file

@ -39,8 +39,8 @@ struct _GstFreeze
GstPad *sinkpad, *srcpad; GstPad *sinkpad, *srcpad;
GQueue *buffers; GPtrArray *buffers;
GstBuffer *current; guint current;
guint max_buffers; guint max_buffers;