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})
#include "log.h"
#include "memfile.h"
+#include "ring.h"
#ifdef USE_TCP
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;
}
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;
}
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");
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;
#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"
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
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */