queuearray: add _peek_tail() and _pop_tail()

API: gst_queue_array_pop_tail()
API: gst_queue_array_peek_tail()

These will be needed later for appsrc.
diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt
index 42adf5b..99cda6c 100644
--- a/docs/libs/gstreamer-libs-sections.txt
+++ b/docs/libs/gstreamer-libs-sections.txt
@@ -928,6 +928,8 @@
 gst_queue_array_pop_head
 gst_queue_array_peek_head
 gst_queue_array_push_tail
+gst_queue_array_pop_tail
+gst_queue_array_peek_tail
 gst_queue_array_is_empty
 gst_queue_array_drop_element
 gst_queue_array_find
diff --git a/libs/gst/base/gstqueuearray.c b/libs/gst/base/gstqueuearray.c
index dc7ec26..0f8ed57 100644
--- a/libs/gst/base/gstqueuearray.c
+++ b/libs/gst/base/gstqueuearray.c
@@ -160,6 +160,7 @@
 {
   gpointer ret;
   g_return_val_if_fail (array != NULL, NULL);
+
   /* empty array */
   if (G_UNLIKELY (array->length == 0))
     return NULL;
@@ -298,6 +299,7 @@
 gst_queue_array_push_tail (GstQueueArray * array, gpointer data)
 {
   g_return_if_fail (array != NULL);
+
   /* Check if we need to make room */
   if (G_UNLIKELY (array->length == array->size))
     gst_queue_array_do_expand (array);
@@ -309,6 +311,69 @@
 }
 
 /**
+ * gst_queue_array_peek_tail: (skip)
+ * @array: a #GstQueueArray object
+ *
+ * Returns the tail of the queue @array, but does not remove it from the queue.
+ *
+ * Returns: The tail of the queue
+ *
+ * Since: 1.14
+ */
+gpointer
+gst_queue_array_peek_tail (GstQueueArray * array)
+{
+  guint len, idx;
+
+  g_return_val_if_fail (array != NULL, NULL);
+
+  len = array->length;
+
+  /* empty array */
+  if (len == 0)
+    return NULL;
+
+  idx = (array->head + (len - 1)) % array->size;
+
+  return *(gpointer *) (array->array + (sizeof (gpointer) * idx));
+}
+
+/**
+ * gst_queue_array_pop_tail: (skip)
+ * @array: a #GstQueueArray object
+ *
+ * Returns the tail of the queue @array and removes
+ * it from the queue.
+ *
+ * Returns: The tail of the queue
+ *
+ * Since: 1.14
+ */
+gpointer
+gst_queue_array_pop_tail (GstQueueArray * array)
+{
+  gpointer ret;
+  guint len, idx;
+
+  g_return_val_if_fail (array != NULL, NULL);
+
+  len = array->length;
+
+  /* empty array */
+  if (len == 0)
+    return NULL;
+
+  idx = (array->head + (len - 1)) % array->size;
+
+  ret = *(gpointer *) (array->array + (sizeof (gpointer) * idx));
+
+  array->tail = idx;
+  array->length--;
+
+  return ret;
+}
+
+/**
  * gst_queue_array_is_empty: (skip)
  * @array: a #GstQueueArray object
  *
diff --git a/libs/gst/base/gstqueuearray.h b/libs/gst/base/gstqueuearray.h
index 4c76ec3..c05780e 100644
--- a/libs/gst/base/gstqueuearray.h
+++ b/libs/gst/base/gstqueuearray.h
@@ -44,6 +44,12 @@
 gpointer        gst_queue_array_peek_head (GstQueueArray * array);
 
 GST_EXPORT
+gpointer        gst_queue_array_pop_tail  (GstQueueArray * array);
+
+GST_EXPORT
+gpointer        gst_queue_array_peek_tail (GstQueueArray * array);
+
+GST_EXPORT
 void            gst_queue_array_push_tail (GstQueueArray * array,
                                            gpointer        data);
 GST_EXPORT
diff --git a/tests/check/libs/queuearray.c b/tests/check/libs/queuearray.c
index 4100178..d9f0f00 100644
--- a/tests/check/libs/queuearray.c
+++ b/tests/check/libs/queuearray.c
@@ -262,6 +262,58 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_array_peek_pop_tail)
+{
+  const guint array_sizes[] = { 0, 1, 2, 5 };
+  guint s;
+
+  for (s = 0; s < G_N_ELEMENTS (array_sizes); ++s) {
+    GstQueueArray *array;
+
+    GST_INFO ("Testing with initial size %u", array_sizes[s]);
+
+    array = gst_queue_array_new (array_sizes[s]);
+    fail_unless_equals_int (gst_queue_array_get_length (array), 0);
+
+    fail_unless (gst_queue_array_peek_tail (array) == NULL);
+    fail_unless (gst_queue_array_pop_tail (array) == NULL);
+
+    gst_queue_array_push_tail (array, GINT_TO_POINTER (42));
+    fail_unless_equals_int (gst_queue_array_get_length (array), 1);
+    fail_unless (gst_queue_array_peek_tail (array) == GINT_TO_POINTER (42));
+    fail_unless (gst_queue_array_peek_head (array) == GINT_TO_POINTER (42));
+    fail_unless_equals_int (gst_queue_array_get_length (array), 1);
+    fail_unless (gst_queue_array_pop_tail (array) == GINT_TO_POINTER (42));
+    fail_unless_equals_int (gst_queue_array_get_length (array), 0);
+
+    gst_queue_array_push_tail (array, GINT_TO_POINTER (42));
+    fail_unless_equals_int (gst_queue_array_get_length (array), 1);
+    fail_unless (gst_queue_array_pop_head (array) == GINT_TO_POINTER (42));
+    fail_unless_equals_int (gst_queue_array_get_length (array), 0);
+    fail_unless (gst_queue_array_peek_tail (array) == NULL);
+    fail_unless (gst_queue_array_pop_tail (array) == NULL);
+
+    gst_queue_array_push_tail (array, GINT_TO_POINTER (43));
+    gst_queue_array_push_tail (array, GINT_TO_POINTER (44));
+
+    fail_unless_equals_int (gst_queue_array_get_length (array), 2);
+    fail_unless_equals_int (GPOINTER_TO_INT (gst_queue_array_peek_head (array)),
+        43);
+    fail_unless_equals_int (GPOINTER_TO_INT (gst_queue_array_peek_tail (array)),
+        44);
+    fail_unless_equals_int (gst_queue_array_get_length (array), 2);
+    fail_unless (gst_queue_array_pop_tail (array) == GINT_TO_POINTER (44));
+    fail_unless_equals_int (gst_queue_array_get_length (array), 1);
+    fail_unless (gst_queue_array_peek_head (array) == GINT_TO_POINTER (43));
+    fail_unless (gst_queue_array_peek_tail (array) == GINT_TO_POINTER (43));
+    fail_unless_equals_int (gst_queue_array_get_length (array), 1);
+
+    gst_queue_array_free (array);
+  }
+}
+
+GST_END_TEST;
+
 static Suite *
 gst_queue_array_suite (void)
 {
@@ -277,6 +329,7 @@
   tcase_add_test (tc_chain, test_array_grow_end);
   tcase_add_test (tc_chain, test_array_drop2);
   tcase_add_test (tc_chain, test_array_grow_from_prealloc1);
+  tcase_add_test (tc_chain, test_array_peek_pop_tail);
 
   return s;
 }
diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def
index cba1a18..d5f0cb7 100644
--- a/win32/common/libgstbase.def
+++ b/win32/common/libgstbase.def
@@ -316,8 +316,10 @@
 	gst_queue_array_new_for_struct
 	gst_queue_array_peek_head
 	gst_queue_array_peek_head_struct
+	gst_queue_array_peek_tail
 	gst_queue_array_pop_head
 	gst_queue_array_pop_head_struct
+	gst_queue_array_pop_tail
 	gst_queue_array_push_tail
 	gst_queue_array_push_tail_struct
 	gst_type_find_helper