diff options
| author | 2026-04-13 17:36:54 -0400 | |
|---|---|---|
| committer | 2026-04-13 17:36:54 -0400 | |
| commit | 4ceadc74f0086168fbc576032ba3e6f23af16e39 (patch) | |
| tree | a542703d78f2b29ac1a756fdceec78e40860bab0 /src/liana/client.c | |
| parent | 77b54c35bf9587450cd636e0d7df37e190e28bfb (diff) | |
| download | camu-4ceadc74f0086168fbc576032ba3e6f23af16e39.tar.gz camu-4ceadc74f0086168fbc576032ba3e6f23af16e39.tar.bz2 camu-4ceadc74f0086168fbc576032ba3e6f23af16e39.zip | |
Changes that went uncommitted for too long
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/liana/client.c')
| -rw-r--r-- | src/liana/client.c | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/src/liana/client.c b/src/liana/client.c index 4d5689f..2b62612 100644 --- a/src/liana/client.c +++ b/src/liana/client.c @@ -13,8 +13,10 @@ enum { RECONNECT_NONE = 0, - RECONNECT_ON_CONNECTION_CLOSED, + RECONNECT_RECOVER, + RECONNECT_SEEK, RECONNECT_SIGNAL_CLIENT, + RECONNECT_DISREGUARD, RECONNECT_DISCONNECTED }; @@ -48,7 +50,7 @@ static void collect_streams(struct lia_client *client, struct nn_packet *packet) u8 type = nn_packet_read_u8(packet); u64 duration = nn_packet_read_u64(packet); s32 index = nn_packet_read_s32(packet); - al_assert(index < 32); + al_assert(index < 64); switch (mode) { case CAMU_NORMAL: { if (type == CAMU_STREAM_AUDIO) { @@ -147,10 +149,6 @@ static void parse_info_packet(struct lia_client *client, struct nn_packet *packe struct camu_codec_stream *stream; al_array_foreach_ptr(client->streams, i, stream) { u8 type = stream->type; - if (type == CAMU_STREAM_SUBTITLE && client->mask == 0) { - log_warn("Ignoring subtitle-only resource."); - goto out; - } if ((selected & (1 << type)) || !(prefs->enabled & (1 << type))) { continue; } @@ -198,6 +196,10 @@ static void parse_info_packet(struct lia_client *client, struct nn_packet *packe lia_vcr_add_track(&client->vcr, track); } } + if (client->mask == (1 << CAMU_STREAM_SUBTITLE)) { + log_warn("Ignoring subtitle-only resource."); + client->mask = 0; + } out: client->callback(client->userdata, LIANA_CLIENT_CONFIGURE_COMPLETE, NULL, NULL); } @@ -211,13 +213,15 @@ static void info_packet_callback(void *userdata, struct nn_packet_stream *stream if (client->mask == 0 || lia_vcr_is_empty(&client->vcr)) { log_warn("Discarding resource with no applicable streams."); al_assert(client->reconnect == RECONNECT_NONE); + client->reconnect = RECONNECT_DISREGUARD; nn_packet_stream_disconnect(&client->data); return; } stream->packet_callback = data_packet_callback; struct nn_packet *rpacket = nn_packet_create(); - nn_packet_write_u32(rpacket, client->mask); + nn_packet_write_u64(rpacket, client->mask); nn_packet_stream_send_packet(stream, rpacket); + client->reconnect = RECONNECT_RECOVER; lia_vcr_start(&client->vcr); } @@ -239,6 +243,7 @@ static bool connection_callback(void *userdata, struct nn_packet_stream *stream) .pos = client->pos, .pause = LIANA_PAUSE_NONE }; + client->at = LIANA_TIMESTAMP_INVALID; client->callback(client->userdata, LIANA_CLIENT_RESUME_AT, NULL, &time); // The value of client->mask will not have changed since connection_closed_callback(). if (client->rec.unconfigured) { @@ -247,18 +252,19 @@ static bool connection_callback(void *userdata, struct nn_packet_stream *stream) } client->callback(client->userdata, LIANA_CLIENT_RECONNECTED, NULL, &client->rec); } else { - al_assert(client->connection_id == 0); + al_assert(client->connection_id == 0 && client->reconnect == RECONNECT_NONE); } stream->packet_sent_callback = packet_sent_callback; struct nn_packet *packet = nn_packet_create(); nn_packet_write_u32(packet, client->node_id); nn_packet_write_u32(packet, client->connection_id); - nn_packet_write_u32(packet, client->mask); + nn_packet_write_u64(packet, client->mask); nn_packet_write_u64(packet, client->pos); if (client->mask == 0) { stream->packet_callback = info_packet_callback; } else { stream->packet_callback = data_packet_callback; + client->reconnect = RECONNECT_RECOVER; lia_vcr_start(&client->vcr); } nn_packet_stream_send_packet(stream, packet); @@ -268,15 +274,26 @@ static bool connection_callback(void *userdata, struct nn_packet_stream *stream) static void connection_closed_callback(void *userdata, struct nn_packet_stream *stream) { struct lia_client *client = (struct lia_client *)userdata; - if (client->reconnect == RECONNECT_ON_CONNECTION_CLOSED) { + + bool reconnect = client->reconnect == RECONNECT_RECOVER || client->reconnect == RECONNECT_SEEK; + if (client->reconnect == RECONNECT_RECOVER) { + al_assert(client->at == LIANA_TIMESTAMP_INVALID); + struct lia_timing time; + client->callback(client->userdata, LIANA_CLIENT_RECOVER_TO, NULL, &time); + client->pos = time.pos; + client->at = time.at; + } + + if (reconnect) { lia_vcr_flush(&client->vcr); } else { lia_vcr_close_all(&client->vcr); } + // If reconnect = SIGNAL_CLIENT, we either never connected or recursed at the reconnect step. if (client->reconnect != RECONNECT_SIGNAL_CLIENT) { client->rec = (struct lia_reconnect_info){ - .reconnect = client->reconnect == RECONNECT_ON_CONNECTION_CLOSED, + .reconnect = reconnect, .unconfigured = client->mask == 0, .mask = client->mask }; @@ -295,10 +312,13 @@ static void connection_closed_callback(void *userdata, struct nn_packet_stream * } al_array_free(client->rec.detached); } - if (client->reconnect == RECONNECT_ON_CONNECTION_CLOSED) { - // If stream_reconnect() errors, the client will be closed on recursion. + + if (reconnect) { + // If stream_reconnect() errors or is aborted, the client will be closed on recursion. client->reconnect = RECONNECT_SIGNAL_CLIENT; - if (!client->mask) { + // A client being seeked before an info packet is another reason mask may + // be unset here. In that case we don't want to forcefully close. + if (!client->rec.unconfigured && !client->mask) { connection_closed_callback(userdata, stream); } else { #ifdef CAMU_DIRECT_MODE @@ -318,6 +338,7 @@ void lia_client_connect(struct lia_client *client, struct nn_event_loop *loop, client->loop = loop; client->node_id = node_id; client->pos = pos; + client->at = LIANA_TIMESTAMP_INVALID; client->mask = 0; al_array_init(client->streams); client->reconnect = RECONNECT_NONE; @@ -336,13 +357,16 @@ void lia_client_connect(struct lia_client *client, struct nn_event_loop *loop, void lia_client_seek(struct lia_client *client, u64 pos, u64 at) { - if (client->reconnect == RECONNECT_DISCONNECTED) return; - // If reconnect = ON_CONNECTION_CLOSED or SIGNAL_CLIENT, we are safe to edit pos + u8 reconnect = client->reconnect; + if (reconnect == RECONNECT_DISCONNECTED || reconnect == RECONNECT_DISREGUARD) { + return; + } + // If reconnect = SEEK, RECOVER or SIGNAL_CLIENT, we are safe to edit pos // and at in-place because they aren't evaluated until connection_callback(). client->pos = pos; client->at = at; - if (client->reconnect == RECONNECT_NONE) { - client->reconnect = RECONNECT_ON_CONNECTION_CLOSED; + if (reconnect == RECONNECT_NONE || reconnect == RECONNECT_RECOVER) { + client->reconnect = RECONNECT_SEEK; nn_packet_stream_disconnect(&client->data); } } @@ -352,7 +376,9 @@ void lia_client_disconnect(struct lia_client *client) u8 reconnect = client->reconnect; al_assert(reconnect != RECONNECT_DISCONNECTED); client->reconnect = RECONNECT_DISCONNECTED; - if (reconnect != RECONNECT_ON_CONNECTION_CLOSED) { + // If reconnect == SIGNAL_CLIENT, stream_disconnect() needs to ensure + // connection_callback() is never called. + if (reconnect != RECONNECT_SEEK && reconnect != RECONNECT_DISREGUARD) { nn_packet_stream_disconnect(&client->data); } } |