1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 117270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org// A ring buffer to hold arbitrary data. Provides no thread safety. Unless 127270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org// otherwise specified, functions return 0 on success and -1 on error. 13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 146b6301588ef2d7b5f5d442aa95bef442a43ead53andrew@webrtc.org#include "webrtc/common_audio/ring_buffer.h" 157270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 169ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org#include <stddef.h> // size_t 17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <stdlib.h> 18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <string.h> 19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 206d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.orgenum Wrap { 216d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org SAME_WRAP, 226d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org DIFF_WRAP 236d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org}; 246d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org 259ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgstruct RingBuffer { 267270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t read_pos; 277270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t write_pos; 287270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t element_count; 297270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t element_size; 306d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org enum Wrap rw_wrap; 316d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org char* data; 329ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org}; 33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 347270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org// Get address of region(s) from which we can read data. 357270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org// If the region is contiguous, |data_ptr_bytes_2| will be zero. 367270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org// If non-contiguous, |data_ptr_bytes_2| will be the size in bytes of the second 377270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org// region. Returns room available to be read or |element_count|, whichever is 387270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org// smaller. 399ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgstatic size_t GetBufferReadRegions(RingBuffer* buf, 407270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t element_count, 417270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org void** data_ptr_1, 427270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t* data_ptr_bytes_1, 437270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org void** data_ptr_2, 447270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t* data_ptr_bytes_2) { 457270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 467270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org const size_t readable_elements = WebRtc_available_read(buf); 477270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org const size_t read_elements = (readable_elements < element_count ? 487270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org readable_elements : element_count); 497270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org const size_t margin = buf->element_count - buf->read_pos; 507270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 517270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // Check to see if read is not contiguous. 527270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (read_elements > margin) { 537270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // Write data in two blocks that wrap the buffer. 546d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org *data_ptr_1 = buf->data + buf->read_pos * buf->element_size; 557270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org *data_ptr_bytes_1 = margin * buf->element_size; 567270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org *data_ptr_2 = buf->data; 577270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org *data_ptr_bytes_2 = (read_elements - margin) * buf->element_size; 587270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } else { 596d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org *data_ptr_1 = buf->data + buf->read_pos * buf->element_size; 607270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org *data_ptr_bytes_1 = read_elements * buf->element_size; 617270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org *data_ptr_2 = NULL; 627270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org *data_ptr_bytes_2 = 0; 637270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 647270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 657270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return read_elements; 667270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org} 67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6891f325586d5e43b13782fe9aa29c14697dc16470andrew@webrtc.orgRingBuffer* WebRtc_CreateBuffer(size_t element_count, size_t element_size) { 699ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org RingBuffer* self = NULL; 709ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (element_count == 0 || element_size == 0) { 7191f325586d5e43b13782fe9aa29c14697dc16470andrew@webrtc.org return NULL; 727270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 737270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 749ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org self = malloc(sizeof(RingBuffer)); 759ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!self) { 7691f325586d5e43b13782fe9aa29c14697dc16470andrew@webrtc.org return NULL; 777270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 797270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->data = malloc(element_count * element_size); 809ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!self->data) { 817270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org free(self); 827270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self = NULL; 8391f325586d5e43b13782fe9aa29c14697dc16470andrew@webrtc.org return NULL; 847270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 857270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 867270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->element_count = element_count; 877270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->element_size = element_size; 886b6301588ef2d7b5f5d442aa95bef442a43ead53andrew@webrtc.org WebRtc_InitBuffer(self); 897270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 9091f325586d5e43b13782fe9aa29c14697dc16470andrew@webrtc.org return self; 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 936b6301588ef2d7b5f5d442aa95bef442a43ead53andrew@webrtc.orgvoid WebRtc_InitBuffer(RingBuffer* self) { 947270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->read_pos = 0; 957270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->write_pos = 0; 967270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->rw_wrap = SAME_WRAP; 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 987270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // Initialize buffer to zeros 997270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org memset(self->data, 0, self->element_count * self->element_size); 1007270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org} 1017270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1029ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgvoid WebRtc_FreeBuffer(void* handle) { 1039ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org RingBuffer* self = (RingBuffer*)handle; 1049ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!self) { 1059ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org return; 1067270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 1077270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1087270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org free(self->data); 1097270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org free(self); 1107270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org} 1117270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1129ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgsize_t WebRtc_ReadBuffer(RingBuffer* self, 1137270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org void** data_ptr, 1147270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org void* data, 1157270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t element_count) { 1167270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1177270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (self == NULL) { 1187270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return 0; 1197270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 1207270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (data == NULL) { 1217270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return 0; 1227270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 1237270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1247270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org { 1257270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org void* buf_ptr_1 = NULL; 1267270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org void* buf_ptr_2 = NULL; 1277270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t buf_ptr_bytes_1 = 0; 1287270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t buf_ptr_bytes_2 = 0; 1297270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org const size_t read_count = GetBufferReadRegions(self, 1307270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org element_count, 1317270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org &buf_ptr_1, 1327270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org &buf_ptr_bytes_1, 1337270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org &buf_ptr_2, 1347270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org &buf_ptr_bytes_2); 1357270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1367270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (buf_ptr_bytes_2 > 0) { 1377270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // We have a wrap around when reading the buffer. Copy the buffer data to 1387270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // |data| and point to it. 1397270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org memcpy(data, buf_ptr_1, buf_ptr_bytes_1); 140267d0133fff6af4153311c612fed12e1bc121ec3bjornv@webrtc.org memcpy(((char*) data) + buf_ptr_bytes_1, buf_ptr_2, buf_ptr_bytes_2); 1419ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org buf_ptr_1 = data; 1429ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org } else if (!data_ptr) { 1439ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org // No wrap, but a memcpy was requested. 1449ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org memcpy(data, buf_ptr_1, buf_ptr_bytes_1); 1459ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org } 1469ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (data_ptr) { 1479ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org // |buf_ptr_1| == |data| in the case of a wrap. 1487270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org *data_ptr = buf_ptr_1; 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1517270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // Update read position 1529ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org WebRtc_MoveReadPtr(self, (int) read_count); 1537270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1547270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return read_count; 1557270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1589ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgsize_t WebRtc_WriteBuffer(RingBuffer* self, 1597270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org const void* data, 1607270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t element_count) { 1619ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!self) { 1627270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return 0; 1637270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 1649ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!data) { 1657270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return 0; 1667270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 1677270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1687270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org { 1699ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org const size_t free_elements = WebRtc_available_write(self); 1707270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org const size_t write_elements = (free_elements < element_count ? free_elements 1717270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org : element_count); 1727270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org size_t n = write_elements; 1737270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org const size_t margin = self->element_count - self->write_pos; 1747270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1757270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (write_elements > margin) { 1767270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // Buffer wrap around when writing. 1776d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org memcpy(self->data + self->write_pos * self->element_size, 1787270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org data, margin * self->element_size); 1797270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->write_pos = 0; 1807270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org n -= margin; 1817270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->rw_wrap = DIFF_WRAP; 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1836d6a43d6e3dc0c83f79df9ce96597d90925e8cadandrew@webrtc.org memcpy(self->data + self->write_pos * self->element_size, 184267d0133fff6af4153311c612fed12e1bc121ec3bjornv@webrtc.org ((const char*) data) + ((write_elements - n) * self->element_size), 1857270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org n * self->element_size); 1867270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->write_pos += n; 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1887270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return write_elements; 1897270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 1907270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org} 1917270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1929ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgint WebRtc_MoveReadPtr(RingBuffer* self, int element_count) { 1939ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!self) { 1947270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return 0; 1957270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 1967270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 1977270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org { 1987270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // We need to be able to take care of negative changes, hence use "int" 1997270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // instead of "size_t". 2009ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org const int free_elements = (int) WebRtc_available_write(self); 2019ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org const int readable_elements = (int) WebRtc_available_read(self); 2027270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org int read_pos = (int) self->read_pos; 2037270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 2047270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (element_count > readable_elements) { 2057270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org element_count = readable_elements; 2067270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 2077270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (element_count < -free_elements) { 2087270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org element_count = -free_elements; 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2117270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org read_pos += element_count; 2127270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (read_pos > (int) self->element_count) { 2137270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // Buffer wrap around. Restart read position and wrap indicator. 2147270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org read_pos -= (int) self->element_count; 2157270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->rw_wrap = SAME_WRAP; 2167270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 2177270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (read_pos < 0) { 2187270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org // Buffer wrap around. Restart read position and wrap indicator. 2197270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org read_pos += (int) self->element_count; 2207270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->rw_wrap = DIFF_WRAP; 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2237270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org self->read_pos = (size_t) read_pos; 2247270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 2257270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return element_count; 2267270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 2277270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org} 2287270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 2299ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgsize_t WebRtc_available_read(const RingBuffer* self) { 2309ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!self) { 2317270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return 0; 2327270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 2337270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org 2347270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org if (self->rw_wrap == SAME_WRAP) { 2357270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return self->write_pos - self->read_pos; 2367270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } else { 2377270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return self->element_count - self->read_pos + self->write_pos; 2387270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2419ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.orgsize_t WebRtc_available_write(const RingBuffer* self) { 2429ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org if (!self) { 2437270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org return 0; 2447270a6bcc288012a340c152ef63cc773c08dbedbbjornv@webrtc.org } 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2469ae1354e250bebaba295048e1cb47a74d33bf8e0andrew@webrtc.org return self->element_count - WebRtc_available_read(self); 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 248