diff options
| author | 2024-11-27 11:32:17 -0500 | |
|---|---|---|
| committer | 2024-11-27 11:32:17 -0500 | |
| commit | 28f56a9e1324fbde6854c72d6b234c2f00748d03 (patch) | |
| tree | 253272dcd76b50a155e0087ee5e70c8b6d4d0034 /src/libsink | |
| parent | 9918d2e947dda7ca470eafc811ddb4c8b632b5d3 (diff) | |
| download | camu-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.c | 66 |
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]); |