+
+ return *(gpointer *) (array->array + (sizeof (gpointer) * array->head));
+}
+
+/**
+ * gst_queue_array_peek_nth: (skip)
+ *
+ * Returns the item at @idx in @array, but does not remove it from the queue.
+ *
+ * Returns: The item, or %NULL if @idx was out of bounds
+ *
+ * Since: 1.16
+ */
+gpointer
+gst_queue_array_peek_nth (GstQueueArray * array, guint idx)
+{
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (idx < array->length, NULL);
+
+ idx = (array->head + idx) % array->size;
+
+ return *(gpointer *) (array->array + (sizeof (gpointer) * idx));
+}
+
+/**
+ * gst_queue_array_peek_nth_struct: (skip)
+ *
+ * Returns the item at @idx in @array, but does not remove it from the queue.
+ *
+ * Returns: The item, or %NULL if @idx was out of bounds
+ *
+ * Since: 1.16
+ */
+gpointer
+gst_queue_array_peek_nth_struct (GstQueueArray * array, guint idx)
+{
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (idx < array->length, NULL);
+
+ idx = (array->head + idx) % array->size;
+
+ return array->array + (array->elt_size * idx);
+}
+
+static void
+gst_queue_array_do_expand (GstQueueArray * array)
+{
+ guint elt_size = array->elt_size;
+ /* newsize is 50% bigger */
+ guint oldsize = array->size;
+ guint newsize = MAX ((3 * oldsize) / 2, oldsize + 1);
+
+ /* copy over data */
+ if (array->tail != 0) {
+ guint8 *array2 = g_malloc0 (elt_size * newsize);
+ guint t1 = array->head;
+ guint t2 = oldsize - array->head;
+
+ /* [0-----TAIL][HEAD------SIZE]
+ *
+ * We want to end up with
+ * [HEAD------------------TAIL][----FREEDATA------NEWSIZE]
+ *
+ * 1) move [HEAD-----SIZE] part to beginning of new array
+ * 2) move [0-------TAIL] part new array, after previous part
+ */
+
+ memcpy (array2, array->array + (elt_size * array->head), t2 * elt_size);
+ memcpy (array2 + t2 * elt_size, array->array, t1 * elt_size);
+
+ g_free (array->array);
+ array->array = array2;
+ array->head = 0;
+ } else {
+ /* Fast path, we just need to grow the array */
+ array->array = g_realloc (array->array, elt_size * newsize);
+ memset (array->array + elt_size * oldsize, 0,
+ elt_size * (newsize - oldsize));
+ }
+ array->tail = oldsize;
+ array->size = newsize;
+}
+
+/**
+ * gst_queue_array_push_element_tail: (skip)
+ * @array: a #GstQueueArray object
+ * @p_struct: address of element or structure to push to the tail of the queue
+ *
+ * Pushes the element at address @p_struct to the tail of the queue @array
+ * (Copies the contents of a structure of the struct_size specified when
+ * creating the queue into the array).
+ *
+ * Since: 1.6
+ */
+void
+gst_queue_array_push_tail_struct (GstQueueArray * array, gpointer p_struct)
+{
+ guint elt_size;
+
+ g_return_if_fail (p_struct != NULL);
+ g_return_if_fail (array != NULL);
+ elt_size = array->elt_size;
+
+ /* Check if we need to make room */
+ if (G_UNLIKELY (array->length == array->size))
+ gst_queue_array_do_expand (array);
+
+ memcpy (array->array + elt_size * array->tail, p_struct, elt_size);
+ array->tail++;
+ array->tail %= array->size;
+ array->length++;