Add mbtk_loopbuff and rtp support.
Change-Id: Idc80af4efb8ff76c4afc59fdf1d3896b453e6ff4
diff --git a/mbtk/libmbtk_lib/common/mbtk_loopbuff.c b/mbtk/libmbtk_lib/common/mbtk_loopbuff.c
new file mode 100755
index 0000000..37dbade
--- /dev/null
+++ b/mbtk/libmbtk_lib/common/mbtk_loopbuff.c
@@ -0,0 +1,309 @@
+/*
+* mbtk_loop_buffer.c
+*
+* MBTK loop buffer sources.
+*
+*/
+/******************************************************************************
+
+ EDIT HISTORY FOR FILE
+
+ WHEN WHO WHAT,WHERE,WHY
+-------- -------- -------------------------------------------------------
+2024/12/5 LiuBin Initial version
+
+******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include "mbtk_str.h"
+#include "mbtk_utils.h"
+#include "mbtk_log.h"
+#include "mbtk_type.h"
+#include "mbtk_loop_buffer.h"
+
+typedef struct {
+ int size;
+ uint8 *buffer;
+
+ int head;
+ int tail;
+
+ int avail_size;
+
+ pthread_mutex_t mutex;
+} loop_buffer_t;
+
+mbtk_loop_buff_handle* mbtk_loopbuff_get(int size)
+{
+ if(size <= 0) {
+ LOGE("size error : %d", size);
+ return NULL;
+ }
+
+ loop_buffer_t *buff = (loop_buffer_t*)malloc(sizeof(loop_buffer_t));
+ if(buff == NULL) {
+ LOGE("malloc() fail:%d", errno);
+ return NULL;
+ }
+
+ memset(buff, 0, sizeof(loop_buffer_t));
+ buff->buffer = (uint8*)malloc(size);
+ if(buff == NULL) {
+ free(buff);
+ LOGE("malloc() fail:%d", errno);
+ return NULL;
+ }
+ buff->size = buff->avail_size = size;
+
+ pthread_mutex_init(&buff->mutex, NULL);
+
+ return buff;
+}
+
+int mbtk_loopbuff_free(mbtk_loop_buff_handle* handle)
+{
+ if(handle == NULL) {
+ LOGE("handle is NULL");
+ return -1;
+ }
+
+ loop_buffer_t *buff = (loop_buffer_t*)handle;
+ if(buff->buffer) {
+ free(buff->buffer);
+ }
+ pthread_mutex_destroy(&buff->mutex);
+ free(buff);
+
+ return 0;
+}
+
+int mbtk_loopbuff_write(mbtk_loop_buff_handle* handle, const void *data, int data_len)
+{
+ if(handle == NULL || data == NULL || data_len <= 0) {
+ LOGE("ARG error.");
+ return -1;
+ }
+
+ loop_buffer_t *loop_buff = (loop_buffer_t*)handle;
+ pthread_mutex_lock(&loop_buff->mutex);
+ if(loop_buff->avail_size == 0) {
+ LOGV("Buffer full.");
+ pthread_mutex_unlock(&loop_buff->mutex);
+ return -1;
+ } else {
+ int size = loop_buff->avail_size >= data_len ? data_len : loop_buff->avail_size;
+ // h t
+ // [...xxxxxxx...]
+ if(loop_buff->tail >= loop_buff->head) {
+ // h t t
+ // [...xxxxxxxyyy.]
+ if(loop_buff->tail + size <= loop_buff->size) {
+ memcpy(loop_buff->buffer + loop_buff->tail, data, size);
+ loop_buff->tail += size;
+ loop_buff->tail %= loop_buff->size;
+ } else {
+ // t h t
+ // [yyy...xxxxyy]
+ int len_right = loop_buff->size - loop_buff->tail; // len_right < size
+ memcpy(loop_buff->buffer + loop_buff->tail, data, len_right);
+ loop_buff->tail = 0;
+ memcpy(loop_buff->buffer + loop_buff->tail, data + len_right, size - len_right);
+ loop_buff->tail += (size - len_right);
+ }
+ } else {
+ // t t h
+ // [xxxyyy...xxxxx]
+ memcpy(loop_buff->buffer + loop_buff->tail, data, size);
+ loop_buff->tail += size;
+ loop_buff->tail %= loop_buff->size;
+ }
+ loop_buff->avail_size -= size;
+ pthread_mutex_unlock(&loop_buff->mutex);
+ return size;
+ }
+}
+
+int mbtk_loopbuff_writen(mbtk_loop_buff_handle* handle, const void *data, int data_len)
+{
+ int len_count = 0;
+ // LOGD("mbtk_loopbuff_write() start.");
+ while(len_count < data_len) {
+ int len = mbtk_loopbuff_write(handle, data + len_count, data_len - len_count);
+ if(len > 0) {
+#if 0
+ if(len != data_len - len_count) {
+ LOGD("%d/%d", len, data_len - len_count);
+ }
+#endif
+ len_count += len;
+ } else {
+ usleep(5000);
+ }
+ }
+#if 0
+ if(data_len != len_count) {
+ LOGD("mbtk_loopbuff_write() xxxxxxxxxxxxxxx fail : %d/%d", len_count, data_len);
+ }
+#endif
+ return len_count;
+}
+
+int mbtk_loopbuff_read(mbtk_loop_buff_handle* handle, void *data, int data_len)
+{
+ if(handle == NULL || data == NULL || data_len <= 0) {
+ LOGE("ARG error.");
+ return -1;
+ }
+
+ loop_buffer_t *loop_buff = (loop_buffer_t*)handle;
+ pthread_mutex_lock(&loop_buff->mutex);
+ if(loop_buff->avail_size == loop_buff->size) { // Buffer is empty.
+ pthread_mutex_unlock(&loop_buff->mutex);
+ LOGV("Buffer is empty.");
+ return 0;
+ } else {
+ int size = (loop_buff->size - loop_buff->avail_size) >= data_len ? data_len :
+ (loop_buff->size - loop_buff->avail_size);
+ // h h t
+ // [...yyyxxxx...]
+ if(loop_buff->tail > loop_buff->head) {
+ memcpy(data, loop_buff->buffer + loop_buff->head, size);
+ loop_buff->head += size;
+ } else {
+ // t h h
+ // [xxxxx.....yyyxx]
+ if(loop_buff->head + size <= loop_buff->size) {// [xxt...hxxxxxx]
+ memcpy(data, loop_buff->buffer + loop_buff->head, size);
+ loop_buff->head += size;
+ loop_buff->head %= loop_buff->size;
+ } else {
+ // h t h
+ // [yyyxxxx.....yyy]
+ int len_right = loop_buff->size - loop_buff->head; // len_right < size
+ memcpy(data, loop_buff->buffer + loop_buff->head, len_right);
+ loop_buff->head = 0;
+ memcpy(data + len_right, loop_buff->buffer + loop_buff->head, size - len_right);
+ loop_buff->head += (size - len_right);
+ }
+ }
+ loop_buff->avail_size += size;
+ pthread_mutex_unlock(&loop_buff->mutex);
+ return size;
+ }
+}
+
+int mbtk_loopbuff_readn(mbtk_loop_buff_handle* handle, void *data, int data_len)
+{
+ int len_count = 0;
+ int read_count = 0;
+ while(len_count < data_len) {
+ int len = mbtk_loopbuff_read(handle, data + len_count, data_len - len_count);
+ if(len > 0) {
+ len_count += len;
+ } else {
+ usleep(5000);
+ }
+ read_count++;
+
+ if(read_count >= 20)
+ break;
+ }
+ return len_count;
+}
+
+
+// Only for read seek.
+int mbtk_loopbuff_seek(mbtk_loop_buff_handle* handle, int offset)
+{
+ if(handle == NULL) {
+ LOGE("ARG error.");
+ return -1;
+ }
+
+ if(offset == 0)
+ return 0;
+
+ loop_buffer_t *loop_buff = (loop_buffer_t*)handle;
+ pthread_mutex_lock(&loop_buff->mutex);
+ if(/*loop_buff->avail_size == loop_buff->size || */
+ offset > loop_buff->size || offset < -loop_buff->size) {
+ pthread_mutex_unlock(&loop_buff->mutex);
+ return -1;
+ } else {
+ if(offset > 0) {
+ int change = offset > (loop_buff->size - loop_buff->avail_size) ?
+ (loop_buff->size - loop_buff->avail_size) : offset;
+ loop_buff->head += change;
+ loop_buff->head %= loop_buff->size;
+ } else {
+ int change = -offset > loop_buff->avail_size ? loop_buff->avail_size : -offset;
+ loop_buff->head -= change;
+ if(loop_buff->head < 0)
+ loop_buff->head = loop_buff->size + loop_buff->head;
+ }
+
+ loop_buff->avail_size += offset;
+ pthread_mutex_unlock(&loop_buff->mutex);
+ return 0;
+ }
+}
+
+int mbtk_loopbuff_size(mbtk_loop_buff_handle* handle)
+{
+ if(handle == NULL) {
+ LOGE("ARG error.");
+ return -1;
+ }
+
+ loop_buffer_t *loop_buff = (loop_buffer_t*)handle;
+ int size = 0;
+ pthread_mutex_lock(&loop_buff->mutex);
+ size = loop_buff->size - loop_buff->avail_size;
+ pthread_mutex_unlock(&loop_buff->mutex);
+ return size;
+}
+
+void mbtk_loopbuff_print(mbtk_loop_buff_handle* handle)
+{
+ if(handle == NULL) {
+ LOGE("ARG error.");
+ return;
+ }
+
+ loop_buffer_t *loop_buff = (loop_buffer_t*)handle;
+ pthread_mutex_lock(&loop_buff->mutex);
+ int data_size = loop_buff->size - loop_buff->avail_size;
+ if(data_size <= 0) {
+ LOGD("Buffer is NULL.");
+ } else {
+ uint8 *buff = (uint8*)malloc(data_size);
+ if(buff) {
+ // h t
+ // [...xxxxxxx...]
+ if(loop_buff->tail > loop_buff->head) {
+ memcpy(buff, loop_buff->buffer + loop_buff->head, data_size);
+ } else {
+ // t h
+ // [xxxxx.....xxxxx]
+ int len_right = loop_buff->size - loop_buff->head; // len_right < size
+ memcpy(buff, loop_buff->buffer + loop_buff->head, len_right);
+ if(data_size - len_right > 0) {
+ memcpy(buff + len_right, loop_buff->buffer, data_size - len_right);
+ }
+ }
+
+ LOGD("Head = %d, Tail = %d, Lenght = %d / %d", loop_buff->head, loop_buff->tail,
+ data_size, loop_buff->size);
+ log_hex("DATA", buff, data_size);
+ free(buff);
+ buff = NULL;
+ }
+ }
+ pthread_mutex_unlock(&loop_buff->mutex);
+}
+