summaryrefslogtreecommitdiff
path: root/src/liana
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-03-19 22:13:19 -0400
committerAndrew Opalach <andrew@akon.city> 2025-03-19 22:13:19 -0400
commit2f34d806e42b6d6299ef46284466b98536485839 (patch)
tree9c5eba5a06b8a5f40ae6a89702cc0f0d8c5c3678 /src/liana
parent191d98d306d48ba36d5a5a2eb3583b805a03b2c3 (diff)
downloadcamu-2f34d806e42b6d6299ef46284466b98536485839.tar.gz
camu-2f34d806e42b6d6299ef46284466b98536485839.tar.bz2
camu-2f34d806e42b6d6299ef46284466b98536485839.zip
Change ended entry behavior in list and sink
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/liana')
-rw-r--r--src/liana/client.c15
-rw-r--r--src/liana/client.h5
-rw-r--r--src/liana/list.c73
3 files changed, 36 insertions, 57 deletions
diff --git a/src/liana/client.c b/src/liana/client.c
index 726f8ff..0aec3e5 100644
--- a/src/liana/client.c
+++ b/src/liana/client.c
@@ -179,12 +179,15 @@ static bool connection_callback(void *userdata, struct nn_packet_stream *stream)
.pause = LIANA_PAUSE_NONE
};
client->callback(client->userdata, LIANA_CLIENT_RESUME_AT, NULL, &time);
- bool unconfigured = client->mask == 0;
- if (unconfigured) {
+ struct lia_reconnect_info rec = {
+ .reconnect = true,
+ .unconfigured = client->mask == 0
+ };
+ if (rec.unconfigured) {
al_assert(client->connection_id == 0);
al_log_warn("liana", "Handling reconnect on unconfigured client.");
}
- client->callback(client->userdata, LIANA_CLIENT_RECONNECTED, NULL, &unconfigured);
+ client->callback(client->userdata, LIANA_CLIENT_RECONNECTED, NULL, &rec);
} else {
al_assert(client->connection_id == 0);
}
@@ -212,8 +215,12 @@ static void connection_closed_callback(void *userdata, struct nn_packet_stream *
} else {
lia_vcr_close_all(&client->vcr);
}
+ struct lia_reconnect_info rec = {
+ .reconnect = client->reconnect == RECONNECT_ON_CONNECTION_CLOSED,
+ .unconfigured = client->mask == 0
+ };
// We need to account for REMOVE_BUFFERS possibly running the event loop to wait.
- client->callback(client->userdata, LIANA_CLIENT_REMOVE_BUFFERS, NULL, &client->reconnect);
+ client->callback(client->userdata, LIANA_CLIENT_REMOVE_BUFFERS, NULL, &rec);
if (client->reconnect == RECONNECT_ON_CONNECTION_CLOSED) {
// If reconnect() errors, this will close the client on recursion.
client->reconnect = RECONNECT_SIGNAL_CLIENT;
diff --git a/src/liana/client.h b/src/liana/client.h
index 4e2ff9e..eb84051 100644
--- a/src/liana/client.h
+++ b/src/liana/client.h
@@ -18,6 +18,11 @@ enum {
LIANA_CLIENT_CLOSED
};
+struct lia_reconnect_info {
+ bool reconnect;
+ bool unconfigured;
+};
+
struct lia_prefs {
u8 enabled_mask;
s8 audio_lang;
diff --git a/src/liana/list.c b/src/liana/list.c
index 3e2a350..d5eef48 100644
--- a/src/liana/list.c
+++ b/src/liana/list.c
@@ -43,22 +43,6 @@ void lia_list_init(struct lia_list *list, str *name)
list->cmd = NULL;
}
-static bool assume_ended(struct lia_list_entry *entry, u64 at)
-{
- if (entry->duration == LIANA_TIMESTAMP_INVALID) return false;
- if (entry->ended || entry->duration == 0) return true;
- if (entry->paused_at == LIANA_TIMESTAMP_INVALID && entry->start != LIANA_TIMESTAMP_INVALID) {
- if (entry->offset > entry->duration) {
- return true;
- }
- if (at < entry->start) return false;
- if (at - entry->start >= entry->duration - entry->offset) {
- return true;
- }
- }
- return false;
-}
-
#define META_OPAQUE(op) ((u8[]){ op })
static void signal_meta(struct lia_list *list, struct lia_list_entry *entry, u8 meta)
@@ -169,11 +153,7 @@ static bool handle_add_sink(struct lia_list *list, struct lia_list_sink *sink)
u8 pause;
u64 at = LIANA_TIMESTAMP_INVALID;
u64 seek_pos = current->offset;
- bool ended = assume_ended(current, now);
- if (ended && current->duration != LIANA_TIMESTAMP_INVALID) {
- seek_pos = current->duration;
- }
- if (ended || current->paused_at != LIANA_TIMESTAMP_INVALID) {
+ if (current->paused_at != LIANA_TIMESTAMP_INVALID) {
pause = LIANA_PAUSE_NONE;
} else {
at = now + LIANA_BASE_DELAY;
@@ -188,7 +168,7 @@ static bool handle_add_sink(struct lia_list *list, struct lia_list_sink *sink)
.at = at,
.seek_pos = seek_pos,
.pause = pause,
- .ended = ended
+ .ended = current->ended
};
sink_set(sink, current, list->current, &time);
}
@@ -303,19 +283,13 @@ static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
// Target was never started before.
target->start = at;
} else {
- // An ended entry may never have been paused, but a non-ended entry that wasn't set
- // cannot be unpaused. Checking assume_ended(target) should be safe here as long
- // as it can't go from true to false (consideration for seek?).
- //al_assert(target->paused_at != LIANA_TIMESTAMP_INVALID);
+ // Target is paused or static.
+ al_assert(target->duration == 0 || target->paused_at != LIANA_TIMESTAMP_INVALID);
}
- // These are not equivalent to current/target->ended.
- bool current_ended = assume_ended(current, now);
- bool target_ended = assume_ended(target, now);
-
- // If current is ended or paused.
- if (current_ended || current->paused_at != LIANA_TIMESTAMP_INVALID) {
- if (target_ended || target->paused_at != LIANA_TIMESTAMP_INVALID) {
+ // If current->duration = LIANA_TIMESTAMP_INVALID, handling of a static entry happens on the sink.
+ if (current->duration == 0 || current->paused_at != LIANA_TIMESTAMP_INVALID) {
+ if (target->duration == 0 || target->paused_at != LIANA_TIMESTAMP_INVALID) {
// Swap entries and ignore their clocks.
pause = LIANA_PAUSE_NONE;
} else {
@@ -324,7 +298,7 @@ static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
pause = LIANA_PAUSE_RESUME;
}
} else { // Current is playing.
- if (target_ended || target->paused_at != LIANA_TIMESTAMP_INVALID) {
+ if (target->duration == 0 || target->paused_at != LIANA_TIMESTAMP_INVALID) {
// Pause-swap current, don't touch target's clock.
pause = LIANA_PAUSE_PAUSE;
} else {
@@ -334,13 +308,8 @@ static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
}
}
- // Pause current and set the held flag indicating it should be resumed
- // if it becomes the target of a skip.
- //
- // @TODO: Why not hold an ended entry? The idea of ended entries being
- // unpaused but never held seems like a over-complication.
- // sink-side ended should only reference buffer state? i.e. pause the entries clock even if ended.
- if (!current_ended && current->paused_at == LIANA_TIMESTAMP_INVALID) {
+ // Pause current to be resumed if it becomes the target of a skip (hold).
+ if (current->duration != 0 && current->paused_at == LIANA_TIMESTAMP_INVALID) {
current->paused_at = at;
if (current->paused_at < current->start) {
current->paused_at = current->start;
@@ -350,14 +319,13 @@ static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
current->held = true;
}
- trace("skipto (#%u-#%u): pause: %hhu, held: %s, current_ended: %s, target_ended: %s.",
- current->id, target->id, pause, BOOLSTR(current->held), BOOLSTR(current_ended), BOOLSTR(target_ended));
+ trace("skipto(#%u-#%u): pause: %hhu, held: %s.", current->id, target->id, pause, BOOLSTR(current->held));
struct lia_timing time = {
.at = at,
.seek_pos = target->offset,
.pause = pause,
- .ended = target_ended
+ .ended = target->ended
};
set_current(list, target, index, &time);
@@ -382,13 +350,12 @@ static void handle_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
}
struct lia_list_entry *entry = get_entry_from_sequence(list, sequence);
- al_assert(entry && !entry->held);
+ if (!entry || entry->ended || entry->duration == 0) return;
+ al_assert(!entry->held);
u64 now = nn_get_timestamp();
u8 pause = (entry->paused_at == LIANA_TIMESTAMP_INVALID) ? LIANA_PAUSE_PAUSE : LIANA_PAUSE_RESUME;
u64 at;
- bool ended = assume_ended(entry, now);
- if (ended) return;
switch (pause) {
case LIANA_PAUSE_PAUSE:
@@ -409,13 +376,13 @@ static void handle_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
break;
}
- trace("toggle_pause (#%u): pts: %f, pause: %hhu.", entry->id, pts, pause);
+ trace("toggle_pause(#%u): pts: %f, pause: %hhu.", entry->id, pts, pause);
struct lia_timing time = {
.at = at,
.seek_pos = LIANA_TIMESTAMP_INVALID,
.pause = pause,
- .ended = false
+ .ended = entry->ended
};
struct lia_list_sink *sink;
@@ -436,7 +403,7 @@ static void handle_seek(struct lia_list *list, s32 sequence, u32 id, u64 pos)
struct lia_list_entry *entry = get_entry_from_sequence(list, sequence);
al_assert(entry);
- if (entry->duration == LIANA_TIMESTAMP_INVALID || entry->duration == 0) {
+ if (entry->duration == 0 || entry->duration == LIANA_TIMESTAMP_INVALID) {
warn("Skipping seek on entry with no duration.");
return;
}
@@ -455,13 +422,13 @@ static void handle_seek(struct lia_list *list, s32 sequence, u32 id, u64 pos)
list->idle = false;
- trace("seek (#%u): pos: %f, pause: %hhu.", entry->id, pos / 1000000.0, pause);
+ trace("seek(#%u): pos: %f, pause: %hhu.", entry->id, pos / 1000000.0, pause);
struct lia_timing time = {
.at = at,
.seek_pos = pos,
.pause = pause,
- .ended = false
+ .ended = entry->ended
};
struct lia_list_sink *sink;
@@ -491,7 +458,7 @@ static bool handle_end(struct lia_list *list, u32 id, u32 reset_id)
return true;
}
- trace("end (#%u).", entry->id);
+ trace("end(#%u).", entry->id);
entry->ended = true;
entry->offset = entry->duration;