summaryrefslogtreecommitdiff
path: root/src/libsink
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-11-27 11:32:17 -0500
committerAndrew Opalach <andrew@akon.city> 2024-11-27 11:32:17 -0500
commit28f56a9e1324fbde6854c72d6b234c2f00748d03 (patch)
tree253272dcd76b50a155e0087ee5e70c8b6d4d0034 /src/libsink
parent9918d2e947dda7ca470eafc811ddb4c8b632b5d3 (diff)
downloadcamu-28f56a9e1324fbde6854c72d6b234c2f00748d03.tar.gz
camu-28f56a9e1324fbde6854c72d6b234c2f00748d03.tar.bz2
camu-28f56a9e1324fbde6854c72d6b234c2f00748d03.zip
Sink fixes, update for dependency changes
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/libsink')
-rw-r--r--src/libsink/sink.c66
1 files changed, 35 insertions, 31 deletions
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 2caa973..80414fd 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -43,11 +43,11 @@ enum {
#define BUFFER_EMPTY(buf) ((buf)->state == BUFFER_INIT || (buf)->state == BUFFER_QUEUED)
#ifdef CAMU_SINK_NO_VIDEO
-#define VIDEO_READY_OR_EMPTY(entry) true
+#define VIDEO_ADDED_OR_EMPTY(entry) true
#else
-#define VIDEO_READY_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->video) || (entry)->video.state == BUFFER_ADDED)
+#define VIDEO_ADDED_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->video) || (entry)->video.state == BUFFER_ADDED)
#endif
-#define AUDIO_READY_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->audio) || (entry)->audio.state == BUFFER_ADDED)
+#define AUDIO_ADDED_OR_EMPTY(entry) (BUFFER_EMPTY(&(entry)->audio) || (entry)->audio.state == BUFFER_ADDED)
#ifdef CAMU_SINK_NO_VIDEO
#define VIDEO_REMOVED_OR_EMPTY(entry) true
@@ -354,7 +354,7 @@ void add_audio_if_set_and_buffered(struct camu_sink_entry *entry)
// It's possible for this entry's video buffer to have been added and removed by EOF
// before this point. This needs to be a consideration for keeping sync.
// Same but reversed in add_video_if_set_and_buffered().
- if (VIDEO_READY_OR_EMPTY(entry)) {
+ if (VIDEO_ADDED_OR_EMPTY(entry)) {
maybe_remove_previous(entry->sink);
}
#ifndef CAMU_SINK_LOCAL
@@ -376,7 +376,7 @@ void add_video_if_set_and_buffered(struct camu_sink_entry *entry)
} else if (entry->video.state == BUFFER_SET_OR_BUFFERED) {
entry->video.state = BUFFER_ADDED;
entry->sink->callback(entry->sink->userdata, CAMU_SINK_ADD_BUFFER, CAMU_SINK_VIDEO, &entry->video.buf);
- if (AUDIO_READY_OR_EMPTY(entry)) {
+ if (AUDIO_ADDED_OR_EMPTY(entry)) {
maybe_remove_previous(entry->sink);
}
bool single_frame = camu_video_buffer_is_single_frame(&entry->video.buf);
@@ -388,28 +388,18 @@ void add_video_if_set_and_buffered(struct camu_sink_entry *entry)
}
#endif
-static void switch_to(struct camu_sink *sink, struct camu_sink_entry *entry)
-{
- if (sink->current) {
- if (camu_clock_is_ended(&entry->clock)) {
- remove_entry_buffers(sink, sink->current);
- } else {
- maybe_add_to_previous(sink, sink->current, entry);
- }
- }
- set_or_queue_entry(entry);
- sink->current = entry;
-}
-
static bool end_entry_and_advance_queue(struct camu_sink *sink, struct camu_sink_entry *entry)
{
al_log_info("sink", "Entry ended.");
camu_clock_end(&entry->clock);
if (sink->target) {
- switch_to(sink, sink->target);
+ set_or_queue_entry(sink->target);
+ sink->current = sink->target;
sink->target = NULL;
- }
- if (sink->queued) {
+ return true;
+ } else if (sink->queued) {
+ // TODO: What is the right behavior if sink->queued
+ // and sink->target are both set.
set_or_queue_entry(sink->queued);
sink->current = sink->queued;
sink->queued = NULL;
@@ -519,6 +509,19 @@ static void video_buffer_callback(void *userdata, u8 op)
}
#endif
+static void switch_to(struct camu_sink *sink, struct camu_sink_entry *entry)
+{
+ if (sink->current) {
+ if (camu_clock_is_ended(&entry->clock)) {
+ remove_entry_buffers(sink, sink->current);
+ } else {
+ maybe_add_to_previous(sink, sink->current, entry);
+ }
+ }
+ set_or_queue_entry(entry);
+ sink->current = entry;
+}
+
static void evaluate_latency(struct camu_sink *sink, struct camu_sink_entry *entry)
{
#ifdef CAMU_SINK_LOCAL
@@ -568,7 +571,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
} else {
entry->audio.state = BUFFER_CONFIGURED;
}
- if (VIDEO_READY_OR_EMPTY(entry)) {
+ if (VIDEO_ADDED_OR_EMPTY(entry)) {
evaluate_latency(sink, entry);
}
aki_mutex_unlock(&sink->mutex);
@@ -585,14 +588,16 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
} else {
entry->video.state = BUFFER_CONFIGURED;
}
- if (AUDIO_READY_OR_EMPTY(entry)) {
+ if (AUDIO_ADDED_OR_EMPTY(entry)) {
evaluate_latency(sink, entry);
}
aki_mutex_unlock(&sink->mutex);
break;
case CAMU_STREAM_SUBTITLE:
#ifdef CAMU_HAVE_FFMPEG
- camu_video_buffer_configure_subtitles(&entry->video.buf, stream->av.stream->codecpar);
+ if (!camu_video_buffer_configure_subtitles(&entry->video.buf, stream->av.stream->codecpar)) {
+ // TODO
+ }
#endif
break;
case CAMU_STREAM_ATTACHMENT: {
@@ -943,10 +948,9 @@ static bool set_command_callback(void *userdata, struct aki_rpc_connection *conn
al_log_warn("sink", "Ignoring target on NONE.");
sink->target = NULL;
}
- if (entry == sink->current) {
- break;
+ if (entry != sink->current) {
+ switch_to(sink, entry);
}
- switch_to(sink, entry);
break;
case LIANA_PAUSE_RESUME:
if (sink->target) {
@@ -954,11 +958,11 @@ static bool set_command_callback(void *userdata, struct aki_rpc_connection *conn
sink->target = NULL;
}
camu_clock_resume(&entry->clock, at);
- if (entry == sink->current) {
+ if (entry != sink->current) {
+ switch_to(sink, entry);
+ } else {
camu_audio_buffer_unpause(&entry->audio.buf);
- break;
}
- switch_to(sink, entry);
break;
case LIANA_PAUSE_PAUSE: {
// For target to be set that must mean that current is set and armed to pause.
@@ -1135,7 +1139,7 @@ bool camu_sink_connect(struct camu_sink *sink, u8 type, str *addr, u16 port, str
aki_timer_init(&sink->reconnect_timer, sink->loop, reconnect_timer_callback, sink);
aki_timer_set_repeat(&sink->reconnect_timer, AKI_TS_FROM_USEC(1000000));
aki_rpc_init(&sink->client, sink->loop, connection_callback, connection_closed_callback, sink);
- for (u32 i = 0; i < AL_ARRAY_SIZE(commands); i++) {
+ for (u32 i = 0; i < ARRAY_SIZE(commands); i++) {
commands[i].userdata = sink;
al_assert(sink->callback);
aki_rpc_add_command(&sink->client, &commands[i]);