mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-30 07:42:32 +00:00
queuearray: fix gst_queue_array_drop_element()
https://bugzilla.gnome.org/show_bug.cgi?id=692691
This commit is contained in:
parent
1ee8ec7921
commit
a1568a3054
1 changed files with 54 additions and 28 deletions
|
@ -124,42 +124,68 @@ gst_queue_array_free (GstQueueArray * array)
|
|||
void
|
||||
gst_queue_array_drop_element (GstQueueArray * array, guint idx)
|
||||
{
|
||||
if (idx == array->head) {
|
||||
/* just move the head */
|
||||
int first_item_index = array->head;
|
||||
/* tail points to the first free spot */
|
||||
int last_item_index = (array->tail - 1 + array->size) % array->size;
|
||||
|
||||
g_assert (array->length > 0);
|
||||
|
||||
/* simply case idx == first item */
|
||||
if (idx == first_item_index) {
|
||||
/* move head by plus one */
|
||||
array->head++;
|
||||
array->head %= array->size;
|
||||
array->length--;
|
||||
return;
|
||||
}
|
||||
if (idx == array->tail - 1) {
|
||||
/* just move the tail */
|
||||
|
||||
/* simply case idx == last item */
|
||||
if (idx == last_item_index) {
|
||||
/* move tail minus one, potentially wrapping */
|
||||
array->tail = (array->tail - 1 + array->size) % array->size;
|
||||
array->length--;
|
||||
return;
|
||||
}
|
||||
/* drop the element #idx... and readjust the array */
|
||||
if (array->head < array->tail) {
|
||||
/* Make sure it's within the boundaries */
|
||||
g_assert (array->head < idx && idx <= array->tail);
|
||||
/* ends not wrapped */
|
||||
/* move head-idx to head+1 */
|
||||
memcpy (&array->array[array->head + 1],
|
||||
&array->array[array->head], (idx - array->head) * sizeof (gpointer));
|
||||
array->tail--;
|
||||
} else {
|
||||
/* ends are wrapped */
|
||||
if (idx < array->tail) {
|
||||
/* move idx-tail backwards one */
|
||||
memcpy (&array->array[idx - 1],
|
||||
&array->array[idx], (array->tail - idx) * sizeof (gpointer));
|
||||
array->tail--;
|
||||
} else if (idx >= array->head) {
|
||||
/* move head-idx forwards one */
|
||||
memcpy (&array->array[array->head],
|
||||
&array->array[array->head + 1],
|
||||
(idx - array->head) * sizeof (gpointer));
|
||||
array->head++;
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
|
||||
/* non-wrapped case */
|
||||
if (first_item_index < last_item_index) {
|
||||
g_assert (first_item_index < idx && idx < last_item_index);
|
||||
/* move everything beyond idx one step towards zero in array */
|
||||
memmove (&array->array[idx],
|
||||
&array->array[idx + 1], (last_item_index - idx) * sizeof (gpointer));
|
||||
/* tail might wrap, ie if tail == 0 (and last_item_index == size) */
|
||||
array->tail = (array->tail - 1 + array->size) % array->size;
|
||||
array->length--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* only wrapped cases left */
|
||||
g_assert (first_item_index > last_item_index);
|
||||
|
||||
if (idx < last_item_index) {
|
||||
/* idx is before last_item_index, move data towards zero */
|
||||
memmove (&array->array[idx],
|
||||
&array->array[idx + 1], (last_item_index - idx) * sizeof (gpointer));
|
||||
/* tail should not wrap in this case! */
|
||||
g_assert (array->tail > 0);
|
||||
array->tail--;
|
||||
array->length--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx > first_item_index) {
|
||||
/* idx is after first_item_index, move data to higher indices */
|
||||
memmove (&array->array[first_item_index + 1],
|
||||
&array->array[first_item_index],
|
||||
(idx - first_item_index) * sizeof (gpointer));
|
||||
array->head++;
|
||||
/* head should not wrap in this case! */
|
||||
g_assert (array->head < array->size);
|
||||
array->length--;
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
guint
|
||||
|
|
Loading…
Reference in a new issue