summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bimu/client.c62
-rw-r--r--src/bimu/client.h2
-rw-r--r--src/bimu/common.h1
-rw-r--r--src/bimu/handler.h10
-rw-r--r--src/bimu/handlers/codec_server.c11
-rw-r--r--src/bimu/server.c70
-rw-r--r--src/bimu/server.h4
-rw-r--r--src/buffer/video.c4
-rw-r--r--src/libsink/sink.c39
-rw-r--r--src/tree/tree.c6
-rw-r--r--src/util/blocking_ring_buffer.c12
11 files changed, 143 insertions, 78 deletions
diff --git a/src/bimu/client.c b/src/bimu/client.c
index b05d950..8a72753 100644
--- a/src/bimu/client.c
+++ b/src/bimu/client.c
@@ -1,3 +1,5 @@
+#include <al/log.h>
+
#include "../codec/libav/packet_ext.h"
#include "client.h"
@@ -13,10 +15,29 @@ static void data_connection_callback(void *userdata, struct aki_packet_stream *s
aki_packet_stream_send_packet(&client->data, packet);
}
+static void send_reconnect_packet(struct bmu_client *client)
+{
+ struct aki_packet *packet = aki_packet_create();
+ aki_packet_write_u8(packet, BIMU_CONTROL_RECONNECT);
+ aki_packet_stream_send_packet(&client->control, packet);
+}
+
+static void flush_streams(struct bmu_client *client)
+{
+ struct bmu_client_stream *stream;
+ al_array_foreach(client->streams, i, stream) {
+ stream->client->flush(stream->client);
+ }
+}
+
static void data_connection_closed_callback(void *userdata, struct aki_packet_stream *stream)
{
- (void)userdata;
+ struct bmu_client *client = (struct bmu_client *)userdata;
(void)stream;
+ aki_packet_stream_free(&client->data);
+ client->callback(client->userdata, BIMU_CLIENT_REMOVE_BUFFERS, NULL, NULL);
+ flush_streams(client);
+ send_reconnect_packet(client);
}
static struct bmu_client_stream *stream_from_index(struct bmu_client *client, s32 index)
@@ -32,16 +53,17 @@ static void handle_data_packet_internal(struct bmu_client *client, struct aki_pa
{
struct bmu_client_stream *stream;
switch (aki_packet_read_u8(packet)) {
- case 0:
+ case BIMU_PACKET_DATA:
stream = stream_from_index(client, aki_packet_read_s32(packet));
stream->client->handle_data_packet(stream->client, packet);
break;
- case 1:
+ case BIMU_PACKET_EOF:
al_array_foreach(client->streams, i, stream) {
stream->client->handle_eof(stream->client);
}
break;
- case 2:
+ case BIMU_PACKET_ERROR:
+ al_log_warn("bimu", "Unhandled error packet.");
break;
}
}
@@ -61,7 +83,7 @@ static void packet_sent_callback(void *userdata, struct aki_packet *packet)
aki_packet_free(packet);
}
-static void connect_data(struct bmu_client *client)
+void connect_data(struct bmu_client *client)
{
aki_packet_stream_init(&client->data, AKI_SOCKET_TCP, data_connection_callback,
data_connection_closed_callback, data_packet_callback, packet_sent_callback, client);
@@ -87,6 +109,7 @@ static void control_connection_closed_callback(void *userdata, struct aki_packet
static void parse_info_packet(struct bmu_client *client, struct aki_packet *packet)
{
+ client->duration = aki_packet_read_s64(packet);
u32 count = aki_packet_read_u32(packet);
for (u32 i = 0; i < count; i++) {
struct bmu_client_stream *stream = al_alloc_object(struct bmu_client_stream);
@@ -147,12 +170,23 @@ static void send_subscribe_packet(struct bmu_client *client)
static void parse_start_packet(struct bmu_client *client, struct aki_packet *packet)
{
u64 seek_pos = aki_packet_read_u64(packet);
- u64 ats = aki_packet_read_u64(packet);
+ u64 ts = aki_packet_read_u64(packet);
u8 paused = aki_packet_read_u8(packet);
(void)paused;
struct bmu_seek_req req = {
.base = seek_pos,
- .start = ats
+ .start = ts
+ };
+ client->callback(client->userdata, BIMU_CLIENT_SET, NULL, &req);
+}
+
+static void parse_resume_packet(struct bmu_client *client, struct aki_packet *packet)
+{
+ u64 seek_pos = aki_packet_read_u64(packet);
+ u64 ts = aki_packet_read_u64(packet);
+ struct bmu_seek_req req = {
+ .base = seek_pos,
+ .start = ts
};
client->callback(client->userdata, BIMU_CLIENT_SET, NULL, &req);
}
@@ -176,6 +210,11 @@ static void control_packet_callback(void *userdata, struct aki_packet_stream *st
case BIMU_CONTROL_PAUSE:
break;
case BIMU_CONTROL_RESUME:
+ //parse_resume_packet(client, packet);
+ break;
+ case BIMU_CONTROL_SEEK:
+ client->corked = false;
+ aki_packet_stream_disconnect(&client->data);
break;
default:
break;
@@ -205,6 +244,15 @@ void bmu_client_cork(struct bmu_client *client, bool cork)
client->corked = cork;
}
+void bmu_client_seek(struct bmu_client *client, f64 percent)
+{
+ u64 pos = client->duration * percent;
+ struct aki_packet *packet = aki_packet_create();
+ aki_packet_write_u8(packet, BIMU_CONTROL_SEEK);
+ aki_packet_write_u64(packet, pos);
+ aki_packet_stream_send_packet(&client->control, packet);
+}
+
void bmu_client_free(struct bmu_client *client)
{
aki_packet_stream_free(&client->control);
diff --git a/src/bimu/client.h b/src/bimu/client.h
index 464ee03..0ebf282 100644
--- a/src/bimu/client.h
+++ b/src/bimu/client.h
@@ -23,6 +23,7 @@ struct bmu_client {
struct aki_packet_stream control;
struct aki_packet_stream data;
bool corked;
+ s64 duration;
array(s32) subscribed;
array(struct bmu_client_stream *) streams;
void (*callback)(void *, u8, struct bmu_client_stream *stream, void *);
@@ -31,4 +32,5 @@ struct bmu_client {
void bmu_client_connect(struct bmu_client *client, struct aki_event_loop *loop, str *addr, s32 port, u16 node_id);
void bmu_client_cork(struct bmu_client *client, bool cork);
+void bmu_client_seek(struct bmu_client *client, f64 percent);
void bmu_client_free(struct bmu_client *client);
diff --git a/src/bimu/common.h b/src/bimu/common.h
index fe8e0af..485d454 100644
--- a/src/bimu/common.h
+++ b/src/bimu/common.h
@@ -14,6 +14,7 @@ enum {
enum {
BIMU_CONTROL_INFO = 0,
BIMU_CONTROL_SUBSCRIBE,
+ BIMU_CONTROL_RECONNECT,
BIMU_CONTROL_START,
BIMU_CONTROL_TOGGLE_PAUSE,
BIMU_CONTROL_PAUSE,
diff --git a/src/bimu/handler.h b/src/bimu/handler.h
index f9e8440..9b9d348 100644
--- a/src/bimu/handler.h
+++ b/src/bimu/handler.h
@@ -6,7 +6,7 @@
#include "../cache/handle.h"
struct bmu_server_handler {
- bool (*init)(struct bmu_server_handler *, struct cch_handle *, struct aki_packet_pool *, void *);
+ bool (*init)(struct bmu_server_handler *, struct cch_handle *, struct aki_packet_pool *);
void (*write_info)(struct bmu_server_handler *, struct aki_packet *);
void (*subscribe)(struct bmu_server_handler *, s32, bool);
s64 (*get_duration)(struct bmu_server_handler *);
@@ -17,10 +17,16 @@ struct bmu_server_handler {
};
enum {
+ BIMU_PACKET_DATA = 0,
+ BIMU_PACKET_EOF,
+ BIMU_PACKET_ERROR
+};
+
+enum {
BIMU_CLIENT_SET = 0,
BIMU_CLIENT_CONFIGURE,
BIMU_CLIENT_DATA,
- BIMU_CLIENT_SEEK,
+ BIMU_CLIENT_REMOVE_BUFFERS,
BIMU_CLIENT_EOF,
BIMU_CLIENT_CLOSED
};
diff --git a/src/bimu/handlers/codec_server.c b/src/bimu/handlers/codec_server.c
index 3c27179..99c4e71 100644
--- a/src/bimu/handlers/codec_server.c
+++ b/src/bimu/handlers/codec_server.c
@@ -10,7 +10,7 @@
#include "codec.h"
static bool codec_server_init(struct bmu_server_handler *handler, struct cch_handle *handle,
- struct aki_packet_pool *pool, void *userdata)
+ struct aki_packet_pool *pool)
{
struct bmu_codec_server *codec = (struct bmu_codec_server *)handler;
codec->demux = camu_lav_demuxer_create();
@@ -27,13 +27,13 @@ static bool codec_server_init(struct bmu_server_handler *handler, struct cch_han
#endif
}
codec->pool = pool;
- codec->handler.userdata = userdata;
return true;
}
static void codec_server_write_info(struct bmu_server_handler *handler, struct aki_packet *packet)
{
struct bmu_codec_server *codec = (struct bmu_codec_server *)handler;
+ aki_packet_write_s64(packet, codec->demux->get_duration(codec->demux));
aki_packet_write_u32(packet, codec->demux->streams.size);
struct camu_stream *stream;
al_array_foreach_ptr(codec->demux->streams, i, stream) {
@@ -78,13 +78,12 @@ static bool codec_server_step(struct bmu_server_handler *handler)
struct bmu_codec_server *codec = (struct bmu_codec_server *)handler;
struct aki_packet *packet = aki_packet_pool_get(codec->pool);
if (!packet) return false;
- packet->userdata = codec->handler.userdata;
s32 ret = codec->demux->get_packet(codec->demux, &codec->packet);
if (ret == CAMU_OK) {
aki_packet_write_u8(packet, 0);
switch (codec->packet.type) {
case CAMU_NORMAL: {
- aki_packet_write_s32(packet, 0);
+ aki_packet_write_s32(packet, BIMU_PACKET_DATA);
aki_packet_write_u8(packet, codec->packet.type);
aki_packet_write_buffer(packet, codec->packet.buffer);
break;
@@ -102,11 +101,11 @@ static bool codec_server_step(struct bmu_server_handler *handler)
}
aki_packet_pool_submit(codec->pool, packet);
} else if (ret == CAMU_ERR_EOF) {
- aki_packet_write_u8(packet, 1);
+ aki_packet_write_u8(packet, BIMU_PACKET_EOF);
aki_packet_pool_submit(codec->pool, packet);
return false;
} else {
- aki_packet_write_u8(packet, 2);
+ aki_packet_write_u8(packet, BIMU_PACKET_ERROR);
aki_packet_pool_submit(codec->pool, packet);
return false;
}
diff --git a/src/bimu/server.c b/src/bimu/server.c
index 565f0b1..b823827 100644
--- a/src/bimu/server.c
+++ b/src/bimu/server.c
@@ -5,21 +5,34 @@
#include "server.h"
-#define START_DELAY 700000 // 700ms
+#define START_DELAY 3000000 // 3s
#define DELAY_GIVE 200000 // 200ms
static void control_connection_closed_callback(void *userdata, struct aki_packet_stream *stream)
{
struct bmu_node_connection *connection = (struct bmu_node_connection *)userdata;
(void)stream;
+ struct bmu_node_connection *rconnection;
+ al_array_foreach(connection->node->connections, i, rconnection) {
+ if (rconnection == connection) {
+ al_array_remove_at_iter(connection->node->connections, i);
+ break;
+ }
+ }
aki_packet_stream_free(connection->control);
+ connection->control = NULL;
}
static void data_connection_closed_callback(void *userdata, struct aki_packet_stream *stream)
{
struct bmu_node_connection *connection = (struct bmu_node_connection *)userdata;
(void)stream;
+ connection->running = 0;
+ aki_packet_pool_disable(&connection->pool);
+ aki_thread_join(&connection->thread);
+ aki_packet_pool_enable(&connection->pool);
aki_packet_stream_free(connection->data);
+ connection->data = NULL;
}
static void default_packet_sent_callback(void *userdata, struct aki_packet *packet)
@@ -31,7 +44,7 @@ static void default_packet_sent_callback(void *userdata, struct aki_packet *pack
static void packet_sent_callback(void *userdata, struct aki_packet *packet)
{
struct bmu_node_connection *connection = (struct bmu_node_connection *)userdata;
- aki_packet_pool_return(&connection->node->pool, packet);
+ aki_packet_pool_return(&connection->pool, packet);
}
static void data_packet_callback(void *userdata, struct aki_packet_stream *stream, struct aki_packet *packet)
@@ -43,8 +56,7 @@ static void data_packet_callback(void *userdata, struct aki_packet_stream *strea
static u8 packet_pool_callback(void *userdata, struct aki_packet *packet)
{
- (void)userdata;
- struct bmu_node_connection *connection = (struct bmu_node_connection *)packet->userdata;
+ struct bmu_node_connection *connection = (struct bmu_node_connection *)userdata;
if (connection->data->connected) {
aki_packet_stream_send_packet(connection->data, packet);
return AKI_PACKET_POOL_KEEP;
@@ -73,18 +85,17 @@ static void send_start_packet(struct bmu_node_connection *connection)
{
struct aki_packet *packet = aki_packet_create();
aki_packet_write_u8(packet, BIMU_CONTROL_START);
- u64 ts = aki_get_timestamp();
- u64 ats = ts - START_DELAY;
+ u64 ts = aki_get_timestamp() - START_DELAY;
s64 seek_pos = connection->node->seek_pos;
if (!connection->node->paused) {
if (connection->node->start >= 0) {
- if ((ats - DELAY_GIVE) < (u64)connection->node->start) {
- ats = connection->node->start;
+ if ((ts - DELAY_GIVE) < (u64)connection->node->start) {
+ ts = connection->node->start;
} else {
- seek_pos += ats - connection->node->start;
+ seek_pos += ts - connection->node->start;
}
} else {
- connection->node->start = ats;
+ connection->node->start = ts;
}
}
s64 duration = connection->handler->get_duration(connection->handler);
@@ -93,16 +104,20 @@ static void send_start_packet(struct bmu_node_connection *connection)
// and the start of a stream.
connection->seek_pos = seek_pos > 0 ? seek_pos : -1;
aki_packet_write_u64(packet, seek_pos);
- aki_packet_write_u64(packet, ats);
+ aki_packet_write_u64(packet, ts);
aki_packet_write_u8(packet, connection->node->paused);
aki_packet_stream_send_packet(connection->control, packet);
}
-static void send_seek_packet(struct bmu_node_connection *connection)
+static void send_seek_packet(struct bmu_node *node)
{
- struct aki_packet *packet = aki_packet_create();
- aki_packet_write_u8(packet, BIMU_CONTROL_SEEK);
- aki_packet_stream_send_packet(connection->control, packet);
+ struct aki_packet *packet;
+ struct bmu_node_connection *connection;
+ al_array_foreach(node->connections, i, connection) {
+ packet = aki_packet_create();
+ aki_packet_write_u8(packet, BIMU_CONTROL_SEEK);
+ aki_packet_stream_send_packet(connection->control, packet);
+ }
}
static void control_packet_callback(void *userdata, struct aki_packet_stream *stream, struct aki_packet *packet)
@@ -119,6 +134,10 @@ static void control_packet_callback(void *userdata, struct aki_packet_stream *st
send_start_packet(connection);
break;
}
+ case BIMU_CONTROL_RECONNECT: {
+ send_start_packet(connection);
+ break;
+ }
case BIMU_CONTROL_TOGGLE_PAUSE: {
struct bmu_node *node = connection->node;
u64 pos = aki_packet_read_u64(packet);
@@ -160,8 +179,10 @@ static void control_packet_callback(void *userdata, struct aki_packet_stream *st
}
case BIMU_CONTROL_SEEK: {
u64 pos = aki_packet_read_u64(packet);
+ connection->node->seek_pos = pos;
+ connection->node->start = -1;
connection->seek_pos = pos;
- send_seek_packet(connection);
+ send_seek_packet(connection->node);
break;
}
}
@@ -192,7 +213,7 @@ static void send_control_info_packet(struct bmu_node_connection *connection)
aki_packet_write_u8(packet, BIMU_CONTROL_INFO);
aki_packet_write_u16(packet, connection->id);
connection->handler = bmu_codec_server_create();
- connection->handler->init(connection->handler, &connection->handle, &connection->node->pool, connection);
+ connection->handler->init(connection->handler, &connection->handle, &connection->pool);
connection->handler->write_info(connection->handler, packet);
aki_packet_stream_send_packet(connection->control, packet);
}
@@ -200,7 +221,7 @@ static void send_control_info_packet(struct bmu_node_connection *connection)
static aki_thread_result AKI_THREADCALL handler_thread(void *userdata)
{
struct bmu_node_connection *connection = (struct bmu_node_connection *)userdata;
- while (connection->handler->step(connection->handler)) {}
+ while (connection->running && connection->handler->step(connection->handler)) {}
return 0;
}
@@ -210,14 +231,10 @@ static void maybe_start_handler(struct bmu_node_connection *connection)
if (connection->seek_pos >= 0) {
connection->handler->seek(connection->handler, connection->seek_pos);
}
+ connection->running = 1;
aki_thread_create(&connection->thread, handler_thread, connection);
- connection->running = true;
struct bmu_node *node = connection->node;
if (connection->paused == BIMU_NOT_PAUSED) {
- if (node->start == -1) {
- node->paused = false;
- node->start = aki_get_timestamp() - START_DELAY;
- }
send_resume_packet(connection, connection->seek_pos, node->start);
connection->paused = BIMU_PLAYING;
} else if (connection->paused == BIMU_PAUSED) {
@@ -254,9 +271,10 @@ static void identify_packet_callback(void *userdata, struct aki_packet_stream *s
connection->node = node;
connection->control = NULL;
connection->data = NULL;
+ aki_packet_pool_init(&connection->pool, 16, server->loop, packet_pool_callback, connection);
cch_entry_get_handle(connection->node->entry, &connection->handle);
- connection->paused = BIMU_PLAYING;
- connection->running = false;
+ connection->paused = BIMU_NOT_PAUSED;
+ connection->running = 0;
}
switch (type) {
@@ -274,6 +292,7 @@ static void identify_packet_callback(void *userdata, struct aki_packet_stream *s
// TODO: is it possible for data->data to be non-NULL during normal operation
// (disconnect and reconnect very fast?).
// - Call maybe_cleanup_data in this function?
+ al_assert(!connection->data);
connection->data = stream;
stream->packet_callback = data_packet_callback;
stream->packet_sent_callback = packet_sent_callback;
@@ -323,7 +342,6 @@ u16 bmu_server_create_node(struct bmu_server *server, struct cch_entry *entry)
node->paused = false;
node->start = -1;
node->seek_pos = 0;
- aki_packet_pool_init(&node->pool, 16, server->loop, packet_pool_callback, node);
node->connection_id = 1;
al_array_init(node->connections);
node->server = server;
diff --git a/src/bimu/server.h b/src/bimu/server.h
index 754ab7f..d954fa9 100644
--- a/src/bimu/server.h
+++ b/src/bimu/server.h
@@ -22,7 +22,8 @@ struct bmu_node_connection {
struct bmu_node *node;
struct aki_packet_stream *control;
struct aki_packet_stream *data;
- bool running;
+ struct aki_packet_pool pool;
+ s32 running;
u8 paused;
s64 seek_pos;
struct cch_handle handle;
@@ -36,7 +37,6 @@ struct bmu_node {
bool paused;
s64 start;
s64 seek_pos;
- struct aki_packet_pool pool;
u16 connection_id;
array(struct bmu_node_connection *) connections;
struct bmu_server *server;
diff --git a/src/buffer/video.c b/src/buffer/video.c
index 3d3961b..106e40f 100644
--- a/src/buffer/video.c
+++ b/src/buffer/video.c
@@ -5,8 +5,8 @@
//#define CAMU_VIDEO_BUFFER_FORCE_SCALER
#define BUFFER_WATERMARK_LOW 16 // frames.
-#define BUFFER_WATERMARK_BUFFERED 24
-#define BUFFER_WATERMARK_HIGH 48
+#define BUFFER_WATERMARK_BUFFERED 22
+#define BUFFER_WATERMARK_HIGH 28
#define BUFFER_WATERMARK_RESET BUFFER_WATERMARK_HIGH + 16.
bool camu_video_buffer_init(struct camu_video_buffer *buf, struct camu_clock *clock,
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 5addc0f..d49e87b 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -118,7 +118,7 @@ static void handle_sink_cmd(struct camu_sink *sink, struct camu_sink_cmd *cmd)
}
case SEEK: {
struct camu_sink_entry *entry = (struct camu_sink_entry *)cmd->opaque;
- (void)entry;
+ bmu_client_seek(&entry->client, cmd->value.f);
break;
}
case ENTRY_BUFFERED: {
@@ -220,11 +220,12 @@ static void audio_buffer_callback(void *userdata, u8 op)
});
break;
case CAMU_BUFFER_EOF: {
- aki_mutex_lock(&entry->sink->mutex);
- u8 ret = entry->sink->callback(entry->sink->userdata, CAMU_SINK_SWAP_BUFFER, CAMU_SINK_AUDIO, &entry->audio.buf);
- entry->audio.state = BUFFER_SET_OR_BUFFERED;
- aki_mutex_unlock(&entry->sink->mutex);
- if (ret != CAMU_SINK_BUFFERS_SWAPPED) {
+ //aki_mutex_lock(&entry->sink->mutex);
+ //u8 ret = entry->sink->callback(entry->sink->userdata, CAMU_SINK_SWAP_BUFFER, CAMU_SINK_AUDIO, &entry->audio.buf);
+ //entry->audio.state = BUFFER_SET_OR_BUFFERED;
+ //aki_mutex_unlock(&entry->sink->mutex);
+ //if (ret != CAMU_SINK_BUFFERS_SWAPPED) {
+ if (1) {
// TODO: Can cause popping. Should run a timer
// and if any action would queue_cmd(AUDIO_START) before the
// the timer, don't queue the stop.
@@ -307,12 +308,16 @@ static void client_callback(void *userdata, u8 op, struct bmu_client_stream *str
struct bmu_seek_req *req = (struct bmu_seek_req *)opaque;
camu_clock_set(&entry->clock, req->base, req->start);
camu_audio_buffer_reset(&entry->audio.buf);
+#ifndef CAMU_SINK_NO_VIDEO
+ bool single_frame = camu_video_buffer_is_single_frame(&entry->video.buf);
+ if (!single_frame) {
+ camu_video_buffer_reset(&entry->video.buf);
+ }
+#endif
break;
}
- // A lot of logic here assumes that no data will be sent
- // until all active streams are configured. This is extremely important,
- // if it does not hold true many confusing errors will arise.
case BIMU_CLIENT_CONFIGURE: {
+ // No data can be sent before this step.
switch (stream->type) {
case BIMU_STREAM_AUDIO:
entry->audio.stream = stream;
@@ -363,10 +368,7 @@ static void client_callback(void *userdata, u8 op, struct bmu_client_stream *str
}
break;
}
- case BIMU_CLIENT_SEEK: {
- // Must ensure no more data from the previous
- // stream position is sent during or after this call to seek.
- struct bmu_seek_req *req = (struct bmu_seek_req *)opaque;
+ case BIMU_CLIENT_REMOVE_BUFFERS: {
aki_mutex_lock(&entry->sink->mutex);
if (entry->audio.state == BUFFER_ADDED) {
entry->sink->callback(entry->sink->userdata, CAMU_SINK_REMOVE_BUFFER, CAMU_SINK_AUDIO, &entry->audio.buf);
@@ -393,13 +395,6 @@ static void client_callback(void *userdata, u8 op, struct bmu_client_stream *str
#ifndef CAMU_SINK_NO_VIDEO
}
#endif
- camu_clock_seek(&entry->clock, req->base, req->start);
- camu_audio_buffer_reset(&entry->audio.buf);
-#ifndef CAMU_SINK_NO_VIDEO
- if (!single_frame) {
- camu_video_buffer_reset(&entry->video.buf);
- }
-#endif
break;
}
case BIMU_CLIENT_EOF: {
@@ -598,7 +593,7 @@ void camu_sink_toggle_pause(struct camu_sink *sink)
}
}
-void camu_sink_seek(struct camu_sink *sink, f64 pos)
+void camu_sink_seek(struct camu_sink *sink, f64 precent)
{
aki_mutex_lock(&sink->mutex);
struct camu_sink_entry *current = sink->current;
@@ -606,7 +601,7 @@ void camu_sink_seek(struct camu_sink *sink, f64 pos)
if (current) {
queue_cmd(sink, (struct camu_sink_cmd){
.op = SEEK,
- .value.f = pos,
+ .value.f = precent,
.opaque = current
});
}
diff --git a/src/tree/tree.c b/src/tree/tree.c
index e671d9c..8a0972f 100644
--- a/src/tree/tree.c
+++ b/src/tree/tree.c
@@ -341,12 +341,14 @@ static bool open_db(struct tree_server *tree, str *path)
static u8 line_callback(void *userdata, str *line)
{
struct tree_server *tree = (struct tree_server *)userdata;
+ struct tree_user *user = al_array_at(tree->users, 0);
+ struct tree_list *list = al_array_at(user->lists, 0);
if (al_str_eq(line, al_str_c(";NEXT"))) {
+ tree_list_skip(list, 1);
} else if (al_str_eq(line, al_str_c(";PREV"))) {
+ tree_list_skip(list, -1);
} else if (al_str_eq(line, al_str_c(";SHUFFLE"))) {
} else {
- struct tree_user *user = al_array_at(tree->users, 0);
- struct tree_list *list = al_array_at(user->lists, 0);
tree_list_add_external(list, line);
}
return AKI_LINE_PROCESSOR_CONTINUE;
diff --git a/src/util/blocking_ring_buffer.c b/src/util/blocking_ring_buffer.c
index 2160fec..5cc3325 100644
--- a/src/util/blocking_ring_buffer.c
+++ b/src/util/blocking_ring_buffer.c
@@ -89,9 +89,7 @@ u8 *camu_ring_buffer_get_chunk(struct camu_ring_buffer *buffer, s32 n)
{
aki_mutex_lock(&buffer->mutex);
- if (!buffer->enabled) {
- return NULL;
- }
+ if (!buffer->enabled) return NULL;
if (buffer->end < buffer->start) {
if (buffer->end + n > buffer->size) {
@@ -145,9 +143,7 @@ s32 camu_ring_buffer_read(struct camu_ring_buffer *buffer, u8 **data, s32 n)
*data = &buffer->data[buffer->start];
// If start == end, the buffer is empty.
- if (buffer->start == buffer->end) {
- return 0;
- }
+ if (buffer->start == buffer->end) return 0;
if (buffer->end < buffer->start) {
// If we would read past the valid data in the buffer, instead
@@ -191,9 +187,7 @@ void camu_ring_buffer_unlock(struct camu_ring_buffer *buffer)
void camu_ring_buffer_free(struct camu_ring_buffer *buffer)
{
- if (buffer->data) {
- al_free(buffer->data);
- }
+ if (buffer->data) al_free(buffer->data);
aki_mutex_destroy(&buffer->mutex);
aki_cond_destroy(&buffer->cond);
}