summaryrefslogtreecommitdiff
path: root/src/libsink
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-01-29 16:45:30 -0500
committerAndrew Opalach <andrew@akon.city> 2025-01-29 16:45:30 -0500
commit6134465ddc10f8b43bddf74209f0ec8654595041 (patch)
tree49eb55da3d08abdc7dea9628c3ae9674dfe7afde /src/libsink
parent457a3cc1a04e45e31370d9083186436b0d12ab1d (diff)
downloadcamu-6134465ddc10f8b43bddf74209f0ec8654595041.tar.gz
camu-6134465ddc10f8b43bddf74209f0ec8654595041.tar.bz2
camu-6134465ddc10f8b43bddf74209f0ec8654595041.zip
Fixes and optimizations around seek and loop
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/libsink')
-rw-r--r--src/libsink/sink.c58
-rw-r--r--src/libsink/sink.h3
2 files changed, 42 insertions, 19 deletions
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 54f651b..03dd379 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -610,8 +610,13 @@ void add_audio_if_set_and_buffered(struct camu_sink_entry *entry)
bool ignore_video = true;
#ifndef CAMU_SINK_NO_VIDEO
ignore_video = VIDEO_EMPTY(entry) || VIDEO_IS_SINGLE_FRAME(entry);
+ if (ignore_video) {
+ struct camu_sink *sink = entry->sink;
+ sink->callback(sink->userdata, CAMU_SINK_REFRESH_VIDEO, CAMU_SINK_VIDEO, NULL);
+ }
#endif
camu_audio_buffer_set_no_video(&entry->audio.buf, ignore_video);
+
#ifdef CAMU_SINK_LOCAL
// If we're local we don't have to worry about syncing audio-only entries.
camu_audio_buffer_set_ignore_desync(&entry->audio.buf, ignore_video);
@@ -798,7 +803,7 @@ static void audio_buffer_callback(void *userdata, u8 op)
// @TODO: This is not well synced. EOF can happen at any time
// while other stuff is happening in the sink. For example
// while seeking, if EOF happens right after a REMOVE_BUFFERS,
- // we might assert during RECONNECT because the entry is ended.
+ // we might assert during RECONNECTED because the entry is ended.
//
// state can be something other than BUFFER_ADDED here
// because it could have changed while waiting on the lock above.
@@ -1058,7 +1063,6 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
nn_mutex_lock(&sink->mutex);
if (reconnect) {
- entry->ended = false;
if (entry == sink->current) {
sink->reconnecting = entry;
if (sink->target) {
@@ -1084,10 +1088,6 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
if (entry->audio.state == BUFFER_ADDED) {
remove_entry_audio_buffer(sink, entry);
}
- // SET_OR_BUFFERED, ADDED, or ENDED.
- if (entry->audio.state > BUFFER_CONFIGURED) {
- entry->audio.state = BUFFER_CONFIGURED;
- }
#ifndef CAMU_SINK_NO_VIDEO
bool ignore_video = VIDEO_EMPTY(entry) || (reconnect && VIDEO_IS_SINGLE_FRAME(entry));
@@ -1095,9 +1095,6 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
if (entry->video.state == BUFFER_ADDED) {
remove_entry_video_buffer(sink, entry);
}
- if (entry->video.state > BUFFER_CONFIGURED) {
- entry->video.state = BUFFER_CONFIGURED;
- }
}
#endif
@@ -1114,6 +1111,29 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
#endif
) { BLOCKING_SLEEP(NNWT_TS_FROM_USEC(2000)); }
+ // Reset possible ENDED state here in case the entry ended at
+ // some pointer after unlocking to block above.
+ nn_mutex_lock(&sink->mutex);
+
+ if (reconnect) {
+ entry->ended = false;
+ }
+
+ // SET_OR_BUFFERED, ADDED, or ENDED.
+ if (entry->audio.state > BUFFER_CONFIGURED) {
+ entry->audio.state = BUFFER_CONFIGURED;
+ }
+
+#ifndef CAMU_SINK_NO_VIDEO
+ if (!ignore_video) {
+ if (entry->video.state > BUFFER_CONFIGURED) {
+ entry->video.state = BUFFER_CONFIGURED;
+ }
+ }
+#endif
+
+ nn_mutex_unlock(&sink->mutex);
+
if (reconnect) {
if (!AUDIO_EMPTY(entry)) {
camu_audio_buffer_reset(&entry->audio.buf);
@@ -1132,8 +1152,8 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
nn_mutex_lock(&sink->mutex);
#if defined LIANA_LIST_SCUFFED_LOOP && !defined CAMU_SINK_NO_VIDEO
struct camu_video_buffer *buf = &entry->video.buf;
- if (time->seek_pos == 0Lu && buf->last_pts >= 0.0) {
- camu_clock_offset(&entry->clock, buf->last_pts);
+ if (time->seek_pos == 0 && buf->last_pts >= 0.0) {
+ camu_clock_loop(&entry->clock, buf->last_pts);
} else {
camu_clock_seek(&entry->clock, time->seek_pos / 1000000.0, time->at);
}
@@ -1337,12 +1357,14 @@ static bool set_command_callback(void *userdata, struct nn_rpc_connection *conn,
#ifdef CAMU_SINK_LOCAL
(void)at;
if (current && !current->ended && !camu_clock_is_paused(&current->clock)) {
+ current->audio.ignore_paused = true;
camu_clock_pause(&current->clock, 0);
}
if (!entry->ended && camu_clock_is_paused(&entry->clock)) {
// This will resume user-paused entries, but whatever.
entry->audio.buffer_paused = false;
+ entry->audio.ignore_paused = false;
camu_clock_resume(&entry->clock, 0);
}
@@ -1520,14 +1542,14 @@ static void connection_callback(void *userdata, struct nn_rpc_connection *conn)
{
struct camu_sink *sink = (struct camu_sink *)userdata;
sink->conn = conn;
- nn_timer_stop(&sink->reconnect_timer);
+ nn_timer_stop(&sink->periodic_timer);
struct nn_packet *packet = nn_rpc_get_packet(&sink->client, CAMU_SERVER_IDENTIFY);
nn_packet_write_u8(packet, CAMU_SINK);
nn_packet_write_str(packet, &sink->name);
nn_rpc_connection_command(sink->conn, packet, idd_callback, sink);
}
-static void reconnect_timer_callback(void *userdata, struct nn_timer *timer)
+static void periodic_timer_callback(void *userdata, struct nn_timer *timer)
{
struct camu_sink *sink = (struct camu_sink *)userdata;
(void)timer;
@@ -1541,15 +1563,15 @@ static void connection_closed_callback(void *userdata, struct nn_rpc_connection
al_assert(sink->conn == conn);
sink->conn = NULL;
}
- nn_timer_again(&sink->reconnect_timer);
+ nn_timer_again(&sink->periodic_timer);
}
bool camu_sink_connect(struct camu_sink *sink, u8 type, str *addr, u16 port, str *name)
{
al_str_clone(&sink->name, name);
sink->type = type;
- nn_timer_init(&sink->reconnect_timer, sink->loop, reconnect_timer_callback, sink);
- nn_timer_set_repeat(&sink->reconnect_timer, NNWT_TS_FROM_USEC(1000000));
+ nn_timer_init(&sink->periodic_timer, sink->loop, periodic_timer_callback, sink);
+ nn_timer_set_repeat(&sink->periodic_timer, NNWT_TS_FROM_USEC(1000000));
nn_rpc_init(&sink->client, sink->loop, connection_callback, connection_closed_callback, sink);
for (u32 i = 0; i < ARRAY_SIZE(commands); i++) {
commands[i].userdata = sink;
@@ -1660,8 +1682,8 @@ void camu_sink_stop(struct camu_sink *sink)
void camu_sink_close(struct camu_sink *sink)
{
- nn_timer_stop(&sink->reconnect_timer);
- nn_timer_disable(&sink->reconnect_timer);
+ nn_timer_stop(&sink->periodic_timer);
+ nn_timer_disable(&sink->periodic_timer);
if (sink->conn) nn_rpc_conn_disconnect(sink->conn);
struct camu_sink_entry *entry;
al_array_foreach_rev(sink->entries, i, entry) {
diff --git a/src/libsink/sink.h b/src/libsink/sink.h
index 68fac15..6845c6d 100644
--- a/src/libsink/sink.h
+++ b/src/libsink/sink.h
@@ -28,6 +28,7 @@ enum {
CAMU_SINK_REMOVE_BUFFER,
CAMU_SINK_START,
CAMU_SINK_STOP,
+ CAMU_SINK_REFRESH_VIDEO,
CAMU_SINK_CLEAR,
CAMU_SINK_MOCK_CLOSE,
CAMU_SINK_EXIT
@@ -79,7 +80,7 @@ struct camu_sink {
struct nn_rpc client;
struct nn_rpc_connection *conn;
struct nn_mutex mutex;
- struct nn_timer reconnect_timer;
+ struct nn_timer periodic_timer;
struct nn_signal queue_signal;
queue(struct camu_sink_cmd) queue;
str default_list;