Ring ring ring... has room for improvements
authorvolpol <volpol@packet-gain.de>
Tue, 8 Sep 2020 14:36:35 +0000 (16:36 +0200)
committervolpol <volpol@packet-gain.de>
Wed, 9 Sep 2020 18:24:19 +0000 (20:24 +0200)
CMakeLists.txt
curly.c
itemq.c
ring.c [new file with mode: 0644]
ring.h [new file with mode: 0644]

index e3cbfbe28bb7f47ab9259fe863c70be7d600fe9c..1db1476bafdb27053ad02cd9c6c26cf40980a9c6 100644 (file)
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.6)
 project(HLS)
 set( CMAKE_C_FLAGS "-W -Wall -Wextra" )
 include_directories(${HLS_SOURCE_DIR})
-add_executable(hls curly.c itemq.c m3u8.c memfile.c)
+add_executable(hls curly.c itemq.c m3u8.c memfile.c ring.c)
 include(FindPkgConfig)
 pkg_check_modules(CURL REQUIRED libcurl)
 include_directories(${CURL_INCLUDE_DIR})
diff --git a/curly.c b/curly.c
index fe5c55324d695d7ed6141ca4d1db59db5aeff72e..9d13ab9d91a4930f3bc40feb74d0af1c47523b6a 100644 (file)
--- a/curly.c
+++ b/curly.c
@@ -10,6 +10,7 @@
 
 #include "log.h"
 #include "memfile.h"
+#include "ring.h"
 
 #ifdef USE_TCP
 
@@ -48,6 +49,12 @@ void curly_set_bw_hint(int kbps, int adj){
 static FILE *capf = NULL;
 static const char *cap_base = "hls";
 
+#define RING_SIZE (64 * 1024 * 1024)
+
+static ssize_t dumper(void *ptr, size_t size){
+       return fwrite(ptr, 1, size, capf);
+}
+
 void curly_set_cap_base(const char *s){
        cap_base = s;
 }
@@ -75,11 +82,13 @@ int curly_start_capture(void){
 
     capf = fopen(fname, "w");
 
-    if (capf)
+    if (capf){
         fprintf (stderr, "Starting capture to %s\n", fname);
-    else
+        ring_dump();
+    } else
         fprintf (stderr, "Failed to start capture\n");
 
+
     return (NULL != capf) ? 0 : -1;
 
 }
@@ -131,7 +140,7 @@ size_t fetch_send(void *ptr, size_t size, size_t nmemb, void *stream) {
     if (flag_conn) {
         sent = send(conn, ptr, bytesize, MSG_NOSIGNAL);
 #ifdef USE_CAPTURE
-        if (capf) fwrite(ptr, size, nmemb, capf);
+        if (capf) fwrite(ptr, size, nmemb, capf); else ring_add(ptr, bytesize);
 #endif
         if (sent <= 0) {
             DPRINT("Pious Teardown!\n");
@@ -242,12 +251,21 @@ int curly_init(void) {
     cc = curl_global_init(CURL_GLOBAL_SSL);
     if (cc != CURLE_OK)
         return -1;
+
+#ifdef USE_CAPTURE
+    return ring_open(RING_SIZE, dumper);
+#else
     return 0;
+#endif
+
 }
 
 void curly_cleanup(void) {
     WHOAMI;
     curl_global_cleanup();
+#ifdef USE_CAPTURE
+    ring_close();
+#endif
 }
 
 static CURL *sch;
diff --git a/itemq.c b/itemq.c
index 27257794a956f141e860663c5b338c693d039d72..331173b9831d51c73b5513b553305c666333fd4c 100644 (file)
--- a/itemq.c
+++ b/itemq.c
@@ -13,6 +13,7 @@
 #include "m3u8.h"
 #include "log.h"
 #include "memfile.h"
+#include "ring.h"
 
 #define PLS "/tmp/iq.m3u8"
 #define QVC_MASTER_M3U8 "http://live1.qvc.jp/iPhone/QVC_PC.m3u8"
@@ -208,6 +209,9 @@ void emulate_stream(void) {
         printf("Streaming %s (%lu)\n", curr->url, curr->duration);
 #if 1
         err = curly_stream(curr->url, curr->duration);
+        #ifdef USE_CAPTURE
+        printf ("Ringbuffer is %lu%% filled\n", ring_usage() * 100 / ring_capacity());
+        #endif
 #else
         err = -1; curly_fake_stream();
 #endif
diff --git a/ring.c b/ring.c
new file mode 100644 (file)
index 0000000..78224aa
--- /dev/null
+++ b/ring.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+
+static void *ring;
+static size_t w1;
+static int wrapped;
+static size_t ring_size;
+
+static ssize_t (*dump_callback)(void *, size_t);
+
+int ring_open(size_t size, ssize_t(*dumpcb)(void *, size_t)){
+    ring = malloc(size);
+    if (!ring) return -1;
+    ring_size = size;
+    dump_callback = dumpcb;
+    return 0;
+}
+
+void ring_add(void *data, size_t len){
+    size_t rest;
+
+    rest = ring_size - w1;
+    if (len > ring_size){
+        memcpy(ring, data + len - ring_size, ring_size);
+        wrapped = 1;
+        w1 = 0;
+    } else
+    if (len <= rest){
+        memcpy(ring + w1, data, len);
+        w1 += len;
+    } else {
+        wrapped = 1;
+        memcpy(ring + w1, data, rest);
+        memcpy(ring, data + rest, len - rest);
+        w1 = len - rest;
+    }
+}
+
+size_t ring_capacity(void){
+    return ring_size;
+}
+
+size_t ring_usage(void){
+    return wrapped ? ring_size : w1;
+}
+
+void ring_dump(void){
+    if (wrapped)
+        dump_callback(ring + w1, ring_size - w1);
+     dump_callback(ring, w1);
+    w1 = wrapped = 0;
+}
+
+void ring_close(void){
+    free(ring);
+    ring = NULL;
+    w1 = wrapped = 0;
+}
diff --git a/ring.h b/ring.h
new file mode 100644 (file)
index 0000000..31ec20f
--- /dev/null
+++ b/ring.h
@@ -0,0 +1,11 @@
+#ifndef RING_H_
+#define RING_H_
+
+int ring_open(size_t size, ssize_t(*dumpcb)(void *, size_t));
+void ring_add(void *data, size_t len);
+size_t ring_usage(void);
+size_t ring_capacity(void);
+void ring_dump(void);
+void ring_close(void);
+
+#endif /* RING_H_ */