diff options
| author | 2024-01-07 17:58:16 -0500 | |
|---|---|---|
| committer | 2024-01-07 17:58:16 -0500 | |
| commit | 342e613fba5849c11a07d568f765f512f30ea6cf (patch) | |
| tree | 78d361a24cb2df7c6bfd4c4fd087a487df245ffd /src | |
| parent | e6c1c0afc69ee13465bb68a6bdeb35b6876146d4 (diff) | |
| download | camu-342e613fba5849c11a07d568f765f512f30ea6cf.tar.gz camu-342e613fba5849c11a07d568f765f512f30ea6cf.tar.bz2 camu-342e613fba5849c11a07d568f765f512f30ea6cf.zip | |
Rough seek implementation
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src')
| -rw-r--r-- | src/bimu/client.c | 62 | ||||
| -rw-r--r-- | src/bimu/client.h | 2 | ||||
| -rw-r--r-- | src/bimu/common.h | 1 | ||||
| -rw-r--r-- | src/bimu/handler.h | 10 | ||||
| -rw-r--r-- | src/bimu/handlers/codec_server.c | 11 | ||||
| -rw-r--r-- | src/bimu/server.c | 70 | ||||
| -rw-r--r-- | src/bimu/server.h | 4 | ||||
| -rw-r--r-- | src/buffer/video.c | 4 | ||||
| -rw-r--r-- | src/libsink/sink.c | 39 | ||||
| -rw-r--r-- | src/tree/tree.c | 6 | ||||
| -rw-r--r-- | src/util/blocking_ring_buffer.c | 12 |
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); } |