From 5d9854ea44cc3b1aa6cda827e615fae85e2d1af1 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 2 Dec 2017 13:51:21 -0800 Subject: [PATCH] libobs/util: Add funcs to push zeroed data to circlebufs Adds circlebuf_push_front_zero and circlebuf_push_back_zero to conveniently push zeroed data to the front/back of the buffer without having to create an intermediary buffer to accomplish the same thing. --- .../reference-libobs-util-circlebuf.rst | 18 ++++++++ libobs/util/circlebuf.h | 42 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/docs/sphinx/reference-libobs-util-circlebuf.rst b/docs/sphinx/reference-libobs-util-circlebuf.rst index 0fdf98bb8..5d290a741 100644 --- a/docs/sphinx/reference-libobs-util-circlebuf.rst +++ b/docs/sphinx/reference-libobs-util-circlebuf.rst @@ -91,6 +91,24 @@ Circular Buffer Inline Functions --------------------- +.. function:: void circlebuf_push_back_zero(struct circlebuf *cb, size_t size) + + Pushes zeroed data to the end of the circular buffer. + + :param cb: The circular buffer + :param size: Size + +--------------------- + +.. function:: void circlebuf_push_front_zero(struct circlebuf *cb, size_t size) + + Pushes zeroed data to the front of the circular buffer. + + :param cb: The circular buffer + :param size: Size + +--------------------- + .. function:: void circlebuf_peek_front(struct circlebuf *cb, void *data, size_t size) Peeks data at the front of the circular buffer. diff --git a/libobs/util/circlebuf.h b/libobs/util/circlebuf.h index c069d5e5f..e6eaca498 100644 --- a/libobs/util/circlebuf.h +++ b/libobs/util/circlebuf.h @@ -189,6 +189,48 @@ static inline void circlebuf_push_front(struct circlebuf *cb, const void *data, } } +static inline void circlebuf_push_back_zero(struct circlebuf *cb, size_t size) +{ + size_t new_end_pos = cb->end_pos + size; + + cb->size += size; + circlebuf_ensure_capacity(cb); + + if (new_end_pos > cb->capacity) { + size_t back_size = cb->capacity - cb->end_pos; + size_t loop_size = size - back_size; + + if (back_size) + memset((uint8_t*)cb->data + cb->end_pos, 0, back_size); + memset(cb->data, 0, loop_size); + + new_end_pos -= cb->capacity; + } else { + memset((uint8_t*)cb->data + cb->end_pos, 0, size); + } + + cb->end_pos = new_end_pos; +} + +static inline void circlebuf_push_front_zero(struct circlebuf *cb, size_t size) +{ + cb->size += size; + circlebuf_ensure_capacity(cb); + + if (cb->start_pos < size) { + size_t back_size = size - cb->start_pos; + + if (cb->start_pos) + memset(cb->data, 0, cb->start_pos); + + cb->start_pos = cb->capacity - back_size; + memset((uint8_t*)cb->data + cb->start_pos, 0, back_size); + } else { + cb->start_pos -= size; + memset((uint8_t*)cb->data + cb->start_pos, 0, size); + } +} + static inline void circlebuf_peek_front(struct circlebuf *cb, void *data, size_t size) {