summaryrefslogtreecommitdiff
path: root/src/libsink
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsink')
-rw-r--r--src/libsink/sink.c44
-rw-r--r--src/libsink/sink.h1
2 files changed, 38 insertions, 7 deletions
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index 50adb40..bae6c77 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -23,6 +23,7 @@ enum {
enum {
ADD_BUFFER = 0,
REMOVE_BUFFER,
+ SET_BUFFERED,
START,
STOP,
TOGGLE_PAUSE,
@@ -77,6 +78,21 @@ static void handle_sink_cmd(struct camu_sink *sink, struct camu_sink_cmd *cmd)
}
break;
}
+ case SET_BUFFERED: {
+ switch (cmd->value.i) {
+ case CAMU_SINK_AUDIO: {
+ sink->callback(sink->userdata, CAMU_SINK_SET_BUFFERED, CAMU_SINK_AUDIO, NULL);
+ break;
+ }
+#ifndef CAMU_SINK_NO_VIDEO
+ case CAMU_SINK_VIDEO: {
+ sink->callback(sink->userdata, CAMU_SINK_SET_BUFFERED, CAMU_SINK_VIDEO, NULL);
+ break;
+ }
+#endif
+ }
+ break;
+ }
case START: {
struct camu_sink *sink = (struct camu_sink *)cmd->opaque;
switch (cmd->value.i) {
@@ -179,6 +195,10 @@ static void add_audio_if_set_and_buffered(struct camu_sink_entry *entry)
if (state == BUFFER_SET_OR_BUFFERED) {
entry->sink->callback(entry->sink->userdata, CAMU_SINK_ADD_BUFFER, CAMU_SINK_AUDIO, &entry->audio.buf);
queue_cmd(entry->sink, (struct camu_sink_cmd){
+ .op = SET_BUFFERED,
+ .value.i = CAMU_SINK_AUDIO
+ });
+ queue_cmd(entry->sink, (struct camu_sink_cmd){
.op = START,
.value.i = CAMU_SINK_AUDIO,
.opaque = entry->sink
@@ -230,6 +250,10 @@ static void audio_buffer_callback(void *userdata, u8 op)
.value.i = CAMU_SINK_AUDIO,
.opaque = entry->sink
});
+ queue_cmd(entry->sink, (struct camu_sink_cmd){
+ .op = SET_BUFFERED,
+ .value.i = CAMU_SINK_VIDEO
+ });
}
break;
}
@@ -243,6 +267,10 @@ static void add_video_if_set_and_buffered(struct camu_sink_entry *entry)
if (state == BUFFER_SET_OR_BUFFERED) {
entry->sink->callback(entry->sink->userdata, CAMU_SINK_ADD_BUFFER, CAMU_SINK_VIDEO, &entry->video.buf);
queue_cmd(entry->sink, (struct camu_sink_cmd){
+ .op = SET_BUFFERED,
+ .value.i = CAMU_SINK_VIDEO
+ });
+ queue_cmd(entry->sink, (struct camu_sink_cmd){
.op = START,
.value.i = CAMU_SINK_VIDEO,
.opaque = entry->sink
@@ -543,6 +571,7 @@ bool camu_sink_local_buffer(struct camu_sink *sink, str *unique_id, struct cch_e
.value.f = 0,
.opaque = entry
});
+ aki_mutex_unlock(&sink->mutex);
return true;
}
@@ -599,17 +628,18 @@ void camu_sink_local_set(struct camu_sink *sink, str *unique_id)
{
aki_mutex_lock(&sink->mutex);
struct camu_sink_entry *entry = entry_from_unique_id(sink, unique_id);
- if (sink->current) {
- if (!camu_clock_is_paused(&sink->current->clock)) {
- camu_clock_pause(&sink->current->clock);
- }
- remove_entry_buffers(sink, sink->current);
- }
+ struct camu_sink_entry *previous = sink->current;
sink->current = entry;
add_audio_if_set_and_buffered(entry);
#ifndef CAMU_SINK_NO_VIDEO
add_video_if_set_and_buffered(entry);
#endif
+ if (previous) {
+ if (!camu_clock_is_paused(&previous->clock)) {
+ camu_clock_pause(&previous->clock);
+ }
+ remove_entry_buffers(sink, previous);
+ }
maybe_cleanup_entries(sink);
aki_mutex_unlock(&sink->mutex);
}
@@ -628,6 +658,6 @@ void camu_sink_local_unload(struct camu_sink *sink, str *unique_id)
{
aki_mutex_lock(&sink->mutex);
struct camu_sink_entry *entry = entry_from_unique_id(sink, unique_id);
- if (entry->state == ENTRY_LOADED) entry->state = ENTRY_DISREGUARDED;
+ if (entry && entry->state == ENTRY_LOADED) entry->state = ENTRY_DISREGUARDED;
aki_mutex_unlock(&sink->mutex);
}
diff --git a/src/libsink/sink.h b/src/libsink/sink.h
index e105245..92c18d9 100644
--- a/src/libsink/sink.h
+++ b/src/libsink/sink.h
@@ -30,6 +30,7 @@ enum {
CAMU_SINK_ADD_BUFFER = 0,
CAMU_SINK_REMOVE_BUFFER,
CAMU_SINK_SWAP_BUFFER,
+ CAMU_SINK_SET_BUFFERED,
CAMU_SINK_START,
CAMU_SINK_STOP,
CAMU_SINK_EXIT