summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-03-18 10:56:12 -0400
committerAndrew Opalach <andrew@akon.city> 2025-03-18 10:56:12 -0400
commit191d98d306d48ba36d5a5a2eb3583b805a03b2c3 (patch)
tree3c917adaf66e6d348046beee510a9a1ed1dc1a41 /src
parentf0accac221a53633380f15b4953ca4f4fdfbeca7 (diff)
downloadcamu-191d98d306d48ba36d5a5a2eb3583b805a03b2c3.tar.gz
camu-191d98d306d48ba36d5a5a2eb3583b805a03b2c3.tar.bz2
camu-191d98d306d48ba36d5a5a2eb3583b805a03b2c3.zip
Cleanup
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src')
-rw-r--r--src/buffer/audio.c70
-rw-r--r--src/buffer/video.c18
-rw-r--r--src/buffer/video.h1
-rw-r--r--src/buffer/video_null.h8
-rw-r--r--src/cache/backings/file.c4
-rw-r--r--src/cache/backings/file.h2
-rw-r--r--src/cache/backings/file_common.h (renamed from src/cache/backings/file_common.c)15
-rw-r--r--src/cache/backings/file_mapped.c4
-rw-r--r--src/cache/handle.c2
-rw-r--r--src/cache/handlers/cdio.c23
-rw-r--r--src/cache/handlers/http.c11
-rw-r--r--src/cache/range.h2
-rw-r--r--src/codec/ffmpeg/decoder.c31
-rw-r--r--src/codec/ffmpeg/decoder.h4
-rw-r--r--src/codec/ffmpeg/demuxer.c2
-rw-r--r--src/fruits/cmc/ui/ext.h20
-rw-r--r--src/fruits/cmc/ui/pane_list.c3
-rw-r--r--src/fruits/cmc/ui/pane_search.c2
-rw-r--r--src/fruits/cmc/ui/ui.c9
-rw-r--r--src/fruits/cmsrv/ui.c2
-rw-r--r--src/fruits/cmv/cmv.c11
-rw-r--r--src/fruits/ctv/ctv.c2
-rw-r--r--src/liana/list.c97
-rw-r--r--src/liana/server.c2
-rw-r--r--src/libsink/sink.c136
-rw-r--r--src/libsink/sink.h9
-rw-r--r--src/screen/screen.c6
-rw-r--r--src/screen/screen.h2
-rw-r--r--src/sink/desktop.c11
29 files changed, 248 insertions, 261 deletions
diff --git a/src/buffer/audio.c b/src/buffer/audio.c
index e9ba16c..8bfed20 100644
--- a/src/buffer/audio.c
+++ b/src/buffer/audio.c
@@ -1,3 +1,4 @@
+#define AL_LOG_SECTION "audio_buffer"
#include <al/log.h>
#ifdef CAMU_HAVE_FFMPEG
@@ -59,12 +60,16 @@ bool camu_audio_buffer_init(struct camu_audio_buffer *buf, struct camu_clock *cl
bool camu_audio_buffer_configure(struct camu_audio_buffer *buf, struct camu_codec_stream *stream,
struct camu_mixer *mixer)
{
- camu_audio_format_copy(&buf->fmt.in, &stream->audio.fmt);
- camu_mixer_pick_format(mixer, &buf->fmt);
+ buf->stream = stream;
+
+ struct camu_audio_format *fmt = &stream->audio.fmt;
+ const char *format_name = camu_audio_format_name(fmt->format);
+ info("Stream: %s (%dch) %dHz.", format_name, fmt->channel_count, fmt->sample_rate);
struct camu_audio_format *in = &buf->fmt.in;
struct camu_audio_format *req = &buf->fmt.req;
-
+ camu_audio_format_copy(in, fmt);
+ camu_mixer_pick_format(mixer, &buf->fmt);
buf->fmt.resampler_needed = !camu_resampler_format_matches(&buf->fmt);
if (buf->fmt.resampler_needed) {
#ifdef CAMU_HAVE_FFMPEG
@@ -76,12 +81,10 @@ bool camu_audio_buffer_configure(struct camu_audio_buffer *buf, struct camu_code
#else
return false;
#endif
+ const char *req_format_name = camu_audio_format_name(req->format);
+ info("Resampling to: %s (%dch) %dHz.", req_format_name, req->channel_count, req->sample_rate);
}
- al_log_info("audio_buffer", "Stream: %s (%dch) %dHz -> %s (%dch) %dHz.",
- camu_audio_format_name(in->format), in->channel_count, in->sample_rate,
- camu_audio_format_name(req->format), req->channel_count, req->sample_rate);
-
buf->size = (ptrdiff_t)camu_audio_format_sec_to_bytes(req, BUFFER_SIZE);
buf->data = (u8 *)al_malloc(buf->size);
al_ring_buffer_init(&buf->rb, buf->data, buf->size);
@@ -90,8 +93,6 @@ bool camu_audio_buffer_configure(struct camu_audio_buffer *buf, struct camu_code
buf->mark.buffered = (ptrdiff_t)camu_audio_format_sec_to_bytes(req, BUFFER_MARK_BUFFERED);
camu_peak_buffer_init(&buf->peak, KB(16));
- buf->stream = stream;
-
return true;
}
@@ -150,7 +151,7 @@ static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32
// The maximum space is buf->size - 1.
ptrdiff_t space = al_ring_buffer_space(&buf->rb);
if (!buf->buffered && (buf->size - 1) - space >= buf->mark.buffered) {
- al_log_debug("audio_buffer", "Buffered (mark: %.1fKB).", buf->mark.buffered / 1024.0);
+ debug("Buffered (mark: %.1fKB).", buf->mark.buffered / 1024.0);
buf->callback(buf->userdata, CAMU_BUFFER_BUFFERED);
buf->buffered = true;
}
@@ -163,7 +164,7 @@ static bool push_internal(struct camu_audio_buffer *buf, f64 pts, u8 **data, s32
peak += have;
if (peak >= buf->mark.min) {
// If this happens the writer of this buffer is taking way too long to stop.
- al_log_warn("audio_buffer", "Overrun likely, discarding peak buffer (audio will desync).");
+ warn("Overrun likely, discarding peak buffer (audio will be desynced).");
camu_peak_buffer_flush(&buf->peak);
peak = 0;
}
@@ -199,7 +200,6 @@ static void push_av_frame_internal(struct camu_audio_buffer *buf, AVFrame *frame
void camu_audio_buffer_push(struct camu_audio_buffer *buf, struct camu_codec_frame *frame)
{
al_assert(al_atomic_load(u8)(&buf->flow, AL_ATOMIC_RELAXED) == FLOWING);
-
switch (frame->mode) {
case CAMU_NORMAL: {
s32 sample_count = frame->audio.sample_count;
@@ -215,25 +215,21 @@ void camu_audio_buffer_push(struct camu_audio_buffer *buf, struct camu_codec_fra
}
#endif
}
-
al_free(frame);
}
// flush() always comes from the same thread as push().
void camu_audio_buffer_flush(struct camu_audio_buffer *buf)
{
- al_log_debug("audio_buffer", "Flush requested.");
-
+ debug("Flush requested.");
if (!push_internal(buf, 0.0, NULL, 0)) {
- al_log_debug("audio_buffer", "Buffer filled by flush.");
+ debug("Buffer filled by flush.");
}
-
if (!buf->buffered) {
- al_log_debug("audio_buffer", "Buffered (flush).");
+ debug("Buffered (flush).");
buf->callback(buf->userdata, CAMU_BUFFER_BUFFERED);
buf->buffered = true;
}
-
al_atomic_store(u8)(&buf->flow, FLUSHED, AL_ATOMIC_RELAXED);
}
@@ -305,16 +301,14 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
if (al_atomic_load(u32)(&buf->volume.set, AL_ATOMIC_ACQUIRE) > 0) {
buf->volume.user = al_atomic_load(f32)(&buf->volume.queued, AL_ATOMIC_RELAXED);
#ifdef CAMU_AUDIO_BUFFER_FADE
- if (buf->fade.volume == -1.f) {
- buf->fade.volume = buf->volume.user;
- }
+ if (buf->fade.volume == -1.f) buf->fade.volume = buf->volume.user;
#endif
al_atomic_sub(u32)(&buf->volume.set, 1, AL_ATOMIC_RELEASE);
}
if (!buf->ignore_desync && al_atomic_load(u32)(&buf->unpause, AL_ATOMIC_ACQUIRE) > 0) {
// Queuing multiple resyncs before resuming the stream will cause pops!
- al_log_info("audio_buffer", "Forcing resync.");
+ info("Forcing resync.");
buf->pause = PAUSE_PAUSED;
al_atomic_sub(u32)(&buf->unpause, 1, AL_ATOMIC_RELEASE);
}
@@ -329,14 +323,14 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
#endif
// Unpause and possibly attempt syncing to the clock.
- // PAUSE_PAUSED signifies that the last read was silence, meaning we
- // can skip around in the buffer without worrying about pops.
+ // PAUSE_PAUSED signifies that the last read was silence, meaning we can skip around
+ // in the buffer without worrying about pops.
if (UNLIKELY(buf->pause == PAUSE_PAUSED)) {
if (!buf->ignore_desync) {
pts -= base_pts;
if (pts > 0.0) { // Skip.
ret = MIN((ptrdiff_t)camu_audio_format_sec_to_bytes(fmt, pts), have);
- al_log_info("audio_buffer", "Skipping %fs of audio (%zd bytes).", pts, ret);
+ info("Skipping %fs of audio (%zd bytes).", pts, ret);
ret = al_ring_buffer_discard(&buf->rb, ret);
have -= ret;
base_pts += camu_audio_format_bytes_to_sec(fmt, ret);
@@ -345,7 +339,7 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
pts = -pts;
ret = MIN((ptrdiff_t)camu_audio_format_sec_to_bytes(fmt, pts), req);
if (!buf->logged_delay) {
- al_log_info("audio_buffer", "Delaying audio by %fs.", pts);
+ info("Delaying audio by %fs.", pts);
buf->logged_delay = true;
}
al_memset(data, 0, ret);
@@ -374,7 +368,7 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
// enough for this request.
if (have < req) {
signal = have;
- al_log_debug("audio_buffer", "Flushed (signal: %zd).", signal);
+ debug("Flushed (signal: %zd).", signal);
buf->callback(buf->userdata, CAMU_BUFFER_EOF);
al_atomic_store(u8)(&buf->flow, SIGNALED, AL_ATOMIC_RELEASE);
}
@@ -385,7 +379,7 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
// We hit an underrun because data wasn't coming in fast enough.
// An underrun can also happen in the audio output if read() (this function)
// takes too long. That isn't checked here.
- al_log_warn("audio_buffer", "Underrun (req: %zd, have: %zd).", req, have);
+ warn("Underrun (req: %zd, have: %zd).", req, have);
// If we have data by the next read(), try to skip ahead to maintain sync.
// This might exacerbate the underrun issue but an underrun is already
// unexpected behavior, trying to stay in sync comes first.
@@ -414,25 +408,17 @@ ptrdiff_t camu_audio_buffer_read(struct camu_audio_buffer *buf, u8 *data, ptrdif
}
f32 step = 0.f;
- if (buf->pause == PAUSE_FADING || buf->fade.volume > buf->volume.user) {
- step = -FADE_STEP(fmt);
- } else if (buf->fade.volume < buf->volume.user) {
+ if (buf->pause == PAUSE_FADING || buf->fade.volume != buf->volume.user) {
step = FADE_STEP(fmt);
+ step *= (buf->pause == PAUSE_FADING || buf->fade.volume > buf->volume.user) ? -1.f : 1.f;
+ if (buf->volume.user > 1.f) step *= buf->volume.user;
+ step *= MAX(buf->fade.volume, FADE_MIN);
}
-
if (step != 0.f || buf->fade.volume != 1.f) {
- if (buf->volume.user > 1.f) {
- // Only adjust the step if it's an increase to avoid drawn out
- // fades if the volume is low.
- step *= buf->volume.user;
- }
- step *= MAX(buf->fade.volume, FADE_MIN);
buf->fade.volume = apply_volume(data, req, fmt, buf->fade.volume, buf->volume.user, step);
}
#else
- if (buf->volume.user != 1.f) {
- apply_volume(data, req, fmt, buf->volume.user, 0.f, 0.f);
- }
+ if (buf->volume.user != 1.f) apply_volume(data, req, fmt, buf->volume.user, 0.f, 0.f);
#endif
}
diff --git a/src/buffer/video.c b/src/buffer/video.c
index ed56ff8..54d83af 100644
--- a/src/buffer/video.c
+++ b/src/buffer/video.c
@@ -50,7 +50,6 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code
switch (stream->mode) {
case CAMU_NORMAL: {
buf->single_frame = true;
- buf->avg_frame_duration = 0.0;
info("Stream: %s (%ux%u) IMAGE.", format_name, fmt->width, fmt->height);
break;
}
@@ -58,10 +57,10 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code
case CAMU_FFMPEG_COMPAT: {
AVRational frame_rate = stream->av.stream->avg_frame_rate;
buf->single_frame = stream->duration == 0 || frame_rate.den == 0;
- buf->avg_frame_duration = frame_rate.den > 0 ? av_q2d(av_inv_q(frame_rate)) : 0.0;
if (buf->single_frame) {
info("Stream: %s (%ux%u) IMAGE.", format_name, fmt->width, fmt->height);
} else {
+ buf->avg_frame_duration = (frame_rate.den > 0) ? av_q2d(av_inv_q(frame_rate)) : 0.0;
info("Stream: %s (%ux%u) VIDEO %.3ffps.", format_name, fmt->width, fmt->height, av_q2d(frame_rate));
}
break;
@@ -77,17 +76,18 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code
if (fmt->width > 0 && fmt->height > 0 &&
(fmt->format != CAMU_PIXEL_FORMAT_RGBA && fmt->format != CAMU_PIXEL_FORMAT_RGB)) {
buf->fmt.scaler_needed = true;
-#ifndef CAMU_HAVE_FFMPEG
- return false;
-#endif
req->width = fmt->width;
req->height = fmt->height;
req->format = CAMU_PIXEL_FORMAT_RGBA;
+#ifdef CAMU_HAVE_FFMPEG
buf->scaler = camu_ff_scaler_create();
if (!buf->scaler->init(buf->scaler, &buf->fmt)) {
// Scaler will be freed in video_buffer_free().
return false;
}
+#else
+ return false;
+#endif
const char *req_format_name = camu_pixel_format_name(req->format);
info("Scaling to: %s (%ux%u).", req_format_name, req->width, req->height);
} else {
@@ -110,11 +110,6 @@ void camu_video_buffer_set_latency(struct camu_video_buffer *buf, s32 frames)
buf->latency = frames * buf->avg_frame_duration;
}
-bool camu_video_buffer_is_single_frame(struct camu_video_buffer *buf)
-{
- return buf->single_frame;
-}
-
static void after_push_internal(struct camu_video_buffer *buf)
{
s32 count = buf->queue->count(buf->queue);
@@ -205,9 +200,10 @@ void camu_video_buffer_flush(struct camu_video_buffer *buf)
buf->queue->flush(buf->queue);
if (!buf->buffered) {
s32 count = buf->queue->count(buf->queue);
+ f64 have = count * buf->avg_frame_duration;
buf->buffered = true;
buf->buffered_with_one_frame = count == 1;
- debug("Buffered (flush).");
+ debug("Buffered (mark: %.2fs).", have);
buf->callback(buf->userdata, CAMU_BUFFER_BUFFERED);
}
}
diff --git a/src/buffer/video.h b/src/buffer/video.h
index 401fa48..5bdf267 100644
--- a/src/buffer/video.h
+++ b/src/buffer/video.h
@@ -51,7 +51,6 @@ bool camu_video_buffer_configure(struct camu_video_buffer *buf, struct camu_code
struct camu_renderer *renderer);
bool camu_video_buffer_configure_subtitles(struct camu_video_buffer *buf, struct camu_codec_stream *stream);
void camu_video_buffer_set_latency(struct camu_video_buffer *buf, s32 frames);
-bool camu_video_buffer_is_single_frame(struct camu_video_buffer *buf);
void camu_video_buffer_push(struct camu_video_buffer *buf, struct camu_codec_frame *frame);
void camu_video_buffer_push_subtitle(struct camu_video_buffer *buf, struct camu_codec_packet *packet);
void camu_video_buffer_flush(struct camu_video_buffer *buf);
diff --git a/src/buffer/video_null.h b/src/buffer/video_null.h
index 69da85f..8423b7c 100644
--- a/src/buffer/video_null.h
+++ b/src/buffer/video_null.h
@@ -7,6 +7,7 @@
#include "clock.h"
struct camu_video_buffer {
+ bool single_frame;
f64 avg_frame_duration;
#ifdef CAMU_SCREEN_THREADED
atomic(u8) ref;
@@ -25,6 +26,7 @@ AL_UNUSED_FUNCTION_PUSH
static bool camu_video_buffer_init(struct camu_video_buffer *buf, struct camu_clock *clock)
{
(void)clock;
+ buf->single_frame = false;
buf->avg_frame_duration = 0.0;
#ifdef CAMU_SCREEN_THREADED
al_atomic_store(u8)(&buf->ref, 0, AL_ATOMIC_RELAXED);
@@ -54,12 +56,6 @@ static void camu_video_buffer_set_latency(struct camu_video_buffer *buf, s32 fra
(void)frames;
}
-static bool camu_video_buffer_is_single_frame(struct camu_video_buffer *buf)
-{
- (void)buf;
- return false;
-}
-
static void camu_video_buffer_push(struct camu_video_buffer *buf, struct camu_codec_frame *frame)
{
(void)buf;
diff --git a/src/cache/backings/file.c b/src/cache/backings/file.c
index f421623..9b905ac 100644
--- a/src/cache/backings/file.c
+++ b/src/cache/backings/file.c
@@ -1,7 +1,5 @@
-#include "../range.h"
-
#include "file.h"
-#include "file_common.c"
+#include "file_common.h"
static void file_backing_lock(struct cch_backing *backing)
{
diff --git a/src/cache/backings/file.h b/src/cache/backings/file.h
index 9ffd650..06daac9 100644
--- a/src/cache/backings/file.h
+++ b/src/cache/backings/file.h
@@ -12,8 +12,8 @@ struct cch_backing_file {
struct nn_file file;
off_t size;
union {
- void *map; // CACHE_BACKING_MAPPED
off_t pointer; // CACHE_BACKING_READ
+ void *map; // CACHE_BACKING_MAPPED
} u;
struct nn_mutex mutex;
};
diff --git a/src/cache/backings/file_common.c b/src/cache/backings/file_common.h
index e8bd2ca..98bd420 100644
--- a/src/cache/backings/file_common.c
+++ b/src/cache/backings/file_common.h
@@ -1,3 +1,12 @@
+#pragma once
+
+#include "../backing.h"
+#include "../range.h"
+
+#include "file.h"
+
+AL_UNUSED_FUNCTION_PUSH
+
static off_t file_backing_get_size_estimate(struct cch_backing *backing)
{
struct cch_backing_file *file = (struct cch_backing_file *)backing;
@@ -10,7 +19,9 @@ static off_t file_backing_get_size_estimate(struct cch_backing *backing)
static bool file_open_internal(struct cch_backing_file *file, str *path, size_t size)
{
s32 flags = size != 0 ? NNWT_FILE_CREATE : NNWT_FILE_READONLY;
- if (!nn_file_open(&file->file, path, flags)) return false;
+ if (!nn_file_open(&file->file, path, flags)) {
+ return false;
+ }
if (!size) {
file->size = file->file.size;
cch_backing_fill_range(&file->backing, 0, file->size);
@@ -22,3 +33,5 @@ static bool file_open_internal(struct cch_backing_file *file, str *path, size_t
}
return true;
}
+
+AL_UNUSED_FUNCTION_POP
diff --git a/src/cache/backings/file_mapped.c b/src/cache/backings/file_mapped.c
index e13d602..17620d0 100644
--- a/src/cache/backings/file_mapped.c
+++ b/src/cache/backings/file_mapped.c
@@ -1,7 +1,5 @@
-#include "../range.h"
-
#include "file.h"
-#include "file_common.c"
+#include "file_common.h"
static void file_backing_lock(struct cch_backing *backing)
{
diff --git a/src/cache/handle.c b/src/cache/handle.c
index 1b351a2..b6bbea0 100644
--- a/src/cache/handle.c
+++ b/src/cache/handle.c
@@ -53,7 +53,7 @@ s32 cch_handle_read(struct cch_handle *handle, u8 *buf, s32 size)
}
handle->pointer += available;
trace("read(%u), pointer: %zd.", size, handle->pointer);
- return available > 0 ? (s32)available : CAMU_ERR_EOF;
+ return (available > 0) ? (s32)available : CAMU_ERR_EOF;
}
off_t cch_handle_seek(struct cch_handle *handle, off_t offset, s32 whence)
diff --git a/src/cache/handlers/cdio.c b/src/cache/handlers/cdio.c
index 1b4c44b..3eae813 100644
--- a/src/cache/handlers/cdio.c
+++ b/src/cache/handlers/cdio.c
@@ -1,3 +1,4 @@
+#define AL_LOG_SECTION "cache_cdio"
#include <al/log.h>
#include "../backings/file.h"
@@ -15,13 +16,13 @@ static void cdio_log_messages(struct cch_handler_cdio *cdio)
{
char *error_messages = cdio_cddap_errors(cdio->drive);
if (error_messages) {
- al_log_error("cdio", "\n%s", error_messages);
+ error("\n%s", error_messages);
cdio_cddap_free_messages(error_messages);
}
char *messages = cdio_cddap_messages(cdio->drive);
if (messages) {
- al_log_info("cdio", "\n%s", messages);
+ info("\n%s", messages);
cdio_cddap_free_messages(messages);
}
}
@@ -50,18 +51,18 @@ static nn_thread_result NNWT_THREADCALL cd_read_thread(void *userdata)
size_t size;
u8 *ptr = cdio->backing->get_ptr(cdio->backing, pointer, &size);
if (size < BYTES_PER_STEP) {
- al_log_error("cdio", "Tried to write over expected size during normal operation.");
+ error("Tried to write over expected size during normal operation.");
cdio->backing->unlock(cdio->backing);
break;
}
if (ret == SECTORS_PER_STEP) {
al_memcpy(ptr, nn_buffer_get_ptr(&cdio->buffer, 0), BYTES_PER_STEP);
} else if (ret == -10) {
- al_log_error("cdio", "I/O error, skipping sector.");
+ error("I/O error, skipping sector.");
al_memset(ptr, 0, BYTES_PER_STEP);
ret = SECTORS_PER_STEP;
} else if (ret < 0) {
- al_log_error("cdio", "Fatal error (%d).", ret);
+ error("Fatal error (%d).", ret);
cdio->backing->unlock(cdio->backing);
break;
}
@@ -70,13 +71,13 @@ static nn_thread_result NNWT_THREADCALL cd_read_thread(void *userdata)
cdio->backing->unlock(cdio->backing);
cch_threaded_waits_evaluate(&cdio->waits, cdio->backing);
if (ret < SECTORS_PER_STEP || cdio->sector > cdio->end) {
- al_log_debug("cdio", "Normal CD EOF.");
+ debug("Normal CD EOF.");
break;
}
}
if (cdio->sector <= cdio->end) {
- al_log_warn("cdio", "Disc read cut short (sectors: %zd, end: %zd).", cdio->sector, cdio->end);
+ warn("Disc read cut short (sectors: %zd, end: %zd).", cdio->sector, cdio->end);
// We didn't read the full disc, disable waiters.
cch_threaded_waits_disable_all(&cdio->waits);
}
@@ -134,7 +135,7 @@ static bool open_cd_drive(struct cch_handler_cdio *cdio)
cdio_handle = cdio_open(*cd_drives, DRIVER_UNKNOWN);
drive = cdio_cddap_identify_cdio(cdio_handle, CDDA_MESSAGE_LOGIT, NULL);
} else {
- al_log_error("cdio", "No compatible disc found.");
+ error("No compatible disc found.");
return false;
}
cdio_free_device_list(cd_drives);
@@ -143,19 +144,19 @@ static bool open_cd_drive(struct cch_handler_cdio *cdio)
s32 ret = cdio_cddap_open(drive);
if (ret != 0) {
- al_log_error("cdio", "Unable to open disc (%d).", ret);
+ error("Unable to open disc (%d).", ret);
return false;
}
ret = cdio_cddap_speed_set(drive, 4);
if (ret != 0) {
- al_log_warn("cdio", "Failed to set drive speed (%d).", ret);
+ warn("Failed to set drive speed (%d).", ret);
}
track_t tracks = cdio_cddap_tracks(drive);
track_t first_track = cdio_get_first_track_num(drive->p_cdio);
track_t last_track = cdio_get_last_track_num(drive->p_cdio);
- al_log_info("cdio", "CD with %d tracks loaded (%d-%d).", tracks, first_track, last_track);
+ info("CD with %d tracks loaded (%d-%d).", tracks, first_track, last_track);
al_array_reserve(cdio->handler.entry->chapters, tracks);
lsn_t start = cdio_cddap_disc_firstsector(drive);
diff --git a/src/cache/handlers/http.c b/src/cache/handlers/http.c
index 1856014..d5c06dc 100644
--- a/src/cache/handlers/http.c
+++ b/src/cache/handlers/http.c
@@ -1,3 +1,4 @@
+#define AL_LOG_SECTION "cache_http"
#include <al/log.h>
#include "../backings/memory.h"
@@ -35,23 +36,23 @@ static void http_callback(void *userdata, u8 op, u8 *buf, void *opaque)
}
case NNWT_HTTP_RESPONSE_CODE: {
long response_code = *(long *)opaque;
- al_log_debug("cache_handler_http", "HTTP %ld.", response_code);
+ debug("HTTP %ld.", response_code);
break;
}
case NNWT_HTTP_CONTENT_LENGTH: {
curl_off_t length = *(curl_off_t *)opaque;
- al_log_debug("cache_handler_http", "Content-Length: %"CURL_FORMAT_CURL_OFF_T".", length);
+ debug("Content-Length: %"CURL_FORMAT_CURL_OFF_T".", length);
cch_entry_set_size(http->handler.entry, length);
cch_threaded_waits_signal_any(&http->waits);
break;
}
case NNWT_HTTP_REDIRECT: {
long response_code = *(long *)opaque;
- al_log_debug("cache_handler_http", "Redirect %ld.", response_code);
+ debug("Redirect %ld.", response_code);
break;
}
case NNWT_HTTP_FINISHED:
- al_log_debug("cache_handler_http", "Transfer finished.");
+ debug("Transfer finished.");
break;
case NNWT_HTTP_ERROR:
cch_threaded_waits_disable_all(&http->waits);
@@ -71,7 +72,7 @@ static void handler_http_maybe_spawn_worker(struct cch_handler *handler, size_t
nn_http_set_url(request, &http->url);
nn_http_set_user_agent(request, &USER_AGENT);
nn_http_request_stream(request, NNWT_HTTP_GET, http->loop, http_callback, http);
- al_log_debug("cache_handler_http", "Spawning worker for %.*s.", al_str_fmt(&http->url));
+ debug("Spawning worker for %.*s.", al_str_fmt(&http->url));
}
static bool handler_http_wait_for_range(struct cch_handler *handler, struct cch_handler_wait *wait)
diff --git a/src/cache/range.h b/src/cache/range.h
index d6c7539..2a95953 100644
--- a/src/cache/range.h
+++ b/src/cache/range.h
@@ -1,3 +1,5 @@
+#pragma once
+
#include <al/types.h>
#include "backing.h"
diff --git a/src/codec/ffmpeg/decoder.c b/src/codec/ffmpeg/decoder.c
index dfabe05..a6431b1 100644
--- a/src/codec/ffmpeg/decoder.c
+++ b/src/codec/ffmpeg/decoder.c
@@ -1,5 +1,6 @@
-#include <al/lib.h>
+#define AL_LOG_SECTION "ff_decoder"
#include <al/log.h>
+#include <al/lib.h>
#include <libavutil/cpu.h>
#ifndef CAMU_SINK_NO_VIDEO
@@ -30,7 +31,7 @@ static s32 init_hwframe_context(struct camu_ff_decoder *av, AVCodecContext *cont
{
AVBufferRef *hw_frames_ref;
if (!(hw_frames_ref = av_hwframe_ctx_alloc(hw_device_context))) {
- al_log_error("ff_decoder", "Failed to create hardware frame context.");
+ error("Failed to create hardware frame context.");
return -1;
}
@@ -44,7 +45,7 @@ static s32 init_hwframe_context(struct camu_ff_decoder *av, AVCodecContext *cont
s32 ret = av_hwframe_ctx_init(hw_frames_ref);
if (ret < 0) {
- al_log_error("ff_decoder", "Failed to initialize hardware frame context (%s).", av_err2str(ret));
+ error("Failed to initialize hardware frame context (%s).", av_err2str(ret));
av_buffer_unref(&hw_frames_ref);
return ret;
}
@@ -70,7 +71,7 @@ static enum AVPixelFormat get_hw_format(AVCodecContext *context, const enum AVPi
}
}
- al_log_error("ff_decoder", "Failed to get HW surface format.");
+ error("Failed to get HW surface format.");
return avcodec_default_get_format(context, pix_fmts);
}
@@ -81,7 +82,7 @@ static s32 init_hwdevice_context(struct camu_ff_decoder *av, AVCodecContext *con
s32 ret = av_hwdevice_ctx_create(&av->hw_context, av->hw_device_type, NULL, NULL, 0);
if (ret < 0) {
- al_log_error("ff_decoder", "Failed to create specified HW device.");
+ error("Failed to create specified HW device.");
return ret;
}
@@ -89,7 +90,7 @@ static s32 init_hwdevice_context(struct camu_ff_decoder *av, AVCodecContext *con
// Note that context->extra_hw_frames has the ability to cause corruption.
context->extra_hw_frames = 18;
- al_log_info("ff_decoder", "Using %s hardware decoding.", av_hwdevice_get_type_name(av->hw_device_type));
+ info("Using %s hardware decoding.", av_hwdevice_get_type_name(av->hw_device_type));
return ret;
}
@@ -181,7 +182,7 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend
AVCodecParameters *codecpar = stream->av.stream->codecpar;
const AVCodec *codec = avcodec_find_decoder(codecpar->codec_id);
if (!codec) {
- al_log_error("ff_decoder", "Failed to find decoder.");
+ error("Failed to find decoder.");
goto err;
}
@@ -215,19 +216,19 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend
}
if (av->hw_device_type == AV_HWDEVICE_TYPE_NONE) {
- al_log_warn("ff_decoder", "Hardware accelerated video decoding of %s not supported.", codec->name);
+ warn("Hardware accelerated video decoding of %s not supported.", codec->name);
}
}
#endif
av->codec_context = avcodec_alloc_context3(codec);
if (!av->codec_context) {
- al_log_error("ff_decoder", "Failed to alloc codec context.");
+ error("Failed to alloc codec context.");
goto err;
}
if (avcodec_parameters_to_context(av->codec_context, codecpar) < 0) {
- al_log_error("ff_decoder", "Failed to copy codec parameters.");
+ error("Failed to copy codec parameters.");
goto err;
}
@@ -261,20 +262,20 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend
av->codec_context->thread_count = cpus;
// FF_THREAD_FRAME or FF_THREAD_SLICE.
av->codec_context->thread_type = FF_THREAD_FRAME;
- al_log_info("ff_decoder", "Using %i threads for decoder.", cpus);
+ info("Using %i threads for decoder.", cpus);
}
}
AVDictionary *opts = NULL;
s32 ret = avcodec_open2(av->codec_context, codec, &opts);
if (ret < 0) {
- al_log_error("ff_decoder", "Failed to open codec %s (%s).", codec->name, av_err2str(ret));
+ error("Failed to open codec %s (%s).", codec->name, av_err2str(ret));
goto err;
}
const char *long_name = codec->long_name ? codec->long_name : codec->name;
- s64 kbps = codecpar->bit_rate > 0 ? codecpar->bit_rate / 1000 : 0;
- al_log_info("ff_decoder", "Codec: %s (%s) %lldkbps.", codec->name, long_name, kbps);
+ s64 kbps = (codecpar->bit_rate > 0) ? codecpar->bit_rate / 1000 : 0;
+ info("Codec: %s (%s) %lldkbps.", codec->name, long_name, kbps);
av->callback = callback;
av->userdata = userdata;
@@ -289,7 +290,7 @@ static s32 send_packet(struct camu_ff_decoder *av, AVPacket *pkt)
{
s32 ret = avcodec_send_packet(av->codec_context, pkt);
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
- al_log_error("ff_decoder", "Error sending packet to the decoder (%s).", av_err2str(ret));
+ error("Error sending packet to the decoder (%s).", av_err2str(ret));
}
return ret;
}
diff --git a/src/codec/ffmpeg/decoder.h b/src/codec/ffmpeg/decoder.h
index aa9eb57..db7a6f8 100644
--- a/src/codec/ffmpeg/decoder.h
+++ b/src/codec/ffmpeg/decoder.h
@@ -5,7 +5,9 @@
#include "../codec.h"
-//#define CAMU_FF_DECODER_HWACCEL
+#ifndef CAMU_SINK_NO_VIDEO
+#define CAMU_FF_DECODER_HWACCEL
+#endif
struct camu_ff_decoder {
struct camu_decoder dec;
diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c
index 9764f58..058a423 100644
--- a/src/codec/ffmpeg/demuxer.c
+++ b/src/codec/ffmpeg/demuxer.c
@@ -76,7 +76,7 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
#define GUESS_STREAM_IS_IMAGE(stream) \
(stream->duration >= 0 && stream->nb_frames <= 1 && (stream->avg_frame_rate.den == 0 && stream->r_frame_rate.den > 0))
- s64 default_duration = av->format_context->duration < 0 ? 0 : av->format_context->duration;
+ s64 default_duration = (av->format_context->duration < 0) ? 0 : av->format_context->duration;
av->duration = 0;
for (u32 i = 0; i < av->format_context->nb_streams; i++) {
diff --git a/src/fruits/cmc/ui/ext.h b/src/fruits/cmc/ui/ext.h
new file mode 100644
index 0000000..b09754e
--- /dev/null
+++ b/src/fruits/cmc/ui/ext.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <al/types.h>
+#include <notcurses/notcurses.h>
+
+// Copy-paste from notcurses.h
+static inline s32 ncplane_light_box(struct ncplane *n, u16 attr, u64 channels, s32 ystop, s32 xstop, u32 ctlword)
+{
+ s32 ret = 0;
+ nccell ul = NCCELL_TRIVIAL_INITIALIZER, ur = NCCELL_TRIVIAL_INITIALIZER;
+ nccell ll = NCCELL_TRIVIAL_INITIALIZER, lr = NCCELL_TRIVIAL_INITIALIZER;
+ nccell hl = NCCELL_TRIVIAL_INITIALIZER, vl = NCCELL_TRIVIAL_INITIALIZER;
+ if((ret = nccells_light_box(n, attr, channels, &ul, &ur, &ll, &lr, &hl, &vl)) == 0){
+ ret = ncplane_box(n, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
+ }
+ nccell_release(n, &ul); nccell_release(n, &ur);
+ nccell_release(n, &ll); nccell_release(n, &lr);
+ nccell_release(n, &hl); nccell_release(n, &vl);
+ return ret;
+}
diff --git a/src/fruits/cmc/ui/pane_list.c b/src/fruits/cmc/ui/pane_list.c
index 9a04211..5fc9f81 100644
--- a/src/fruits/cmc/ui/pane_list.c
+++ b/src/fruits/cmc/ui/pane_list.c
@@ -5,6 +5,7 @@
#include "../cmc.h"
#include "ui.h"
+#include "ext.h"
void cmc_lp_init(struct cmc_ui *ui)
{
@@ -137,7 +138,7 @@ static void render_now_playing(struct cmc_ui *ui, struct cmc_list_tab *tab, u32
u64 c = 0;
ncchannels_set_fg_default(&c);
ncplane_cursor_move_yx(ui->lp.n, y, 0);
- ncplane_rounded_box(ui->lp.n, NCSTYLE_NONE, c, height - 1, width - 1, 0);
+ ncplane_light_box(ui->lp.n, NCSTYLE_NONE, c, height - 1, width - 1, 0);
}
void cmc_lp_render(struct cmc_ui *ui)
diff --git a/src/fruits/cmc/ui/pane_search.c b/src/fruits/cmc/ui/pane_search.c
index e273504..3b427ce 100644
--- a/src/fruits/cmc/ui/pane_search.c
+++ b/src/fruits/cmc/ui/pane_search.c
@@ -2,6 +2,8 @@
#include "ui.h"
+AL_ASSERT_TYPE_SIZE(wchar_t, 4);
+
void cmc_sp_init(struct cmc_ui *ui)
{
al_array_init(ui->sp.tabs);
diff --git a/src/fruits/cmc/ui/ui.c b/src/fruits/cmc/ui/ui.c
index 84e514e..9931620 100644
--- a/src/fruits/cmc/ui/ui.c
+++ b/src/fruits/cmc/ui/ui.c
@@ -1,6 +1,7 @@
#include <al/lib.h>
#include "ui.h"
+#include "ext.h"
void cmc_ui_putnwstr_yx(struct ncplane *n, u32 y, u32 x, u32 width, wstr *w)
{
@@ -67,7 +68,7 @@ void cmc_ui_queue_render(struct cmc_ui *ui)
ncplane_erase(ui->oln);
}
- notcurses_render(ui->nc);
+ //notcurses_render(ui->nc);
switch (ui->pane) {
case CMC_PANE_LIST:
@@ -92,7 +93,7 @@ void cmc_ui_queue_render(struct cmc_ui *ui)
u64 c = 0;
ncchannels_set_fg_default(&c);
ncplane_cursor_move_yx(ui->oln, 0, 0);
- ncplane_rounded_box(ui->oln, NCSTYLE_NONE, c, height - 1, width - 1, 0);
+ ncplane_light_box(ui->oln, NCSTYLE_NONE, c, height - 1, width - 1, 0);
}
notcurses_render(ui->nc);
@@ -190,8 +191,8 @@ static bool relayout(struct cmc_ui *ui)
if (ui->oln) ncplane_destroy(ui->oln);
u32 width = ncplane_dim_x(ui->n);
u32 height = ncplane_dim_y(ui->n);
- nopts.margin_r = MAX(6u, (u32)(width / 1.5));
- nopts.margin_b = MAX(2u, height / 3);
+ nopts.margin_r = MAX(6u, width / 2);
+ nopts.margin_b = MAX(2u, height / 2);
nopts.x = nopts.margin_r / 2;
nopts.y = nopts.margin_b / 2;
ui->oln = ncplane_create(ui->n, &nopts);
diff --git a/src/fruits/cmsrv/ui.c b/src/fruits/cmsrv/ui.c
index 9059632..dced71d 100644
--- a/src/fruits/cmsrv/ui.c
+++ b/src/fruits/cmsrv/ui.c
@@ -83,7 +83,7 @@ static void render_log(struct cmsrv_ui *ui)
u32 max_height = ncplane_dim_y(n) - 2;
u32 size = ui->log.messages.count;
- u32 index = size > max_height ? size - max_height : 0;
+ u32 index = (size > max_height) ? size - max_height : 0;
for (u32 i = index; i < size; i++) {
// We can't use putnstr here to control the width because lots of
// these messages will have wide characters.
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index 6285c39..e539f01 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -1,3 +1,4 @@
+#define AL_LOG_SECTION "cmv"
#include <al/log.h>
#include <nnwt/event_loop.h>
#include <nnwt/thread.h>
@@ -124,6 +125,10 @@ s32 window_system_main(s32 argc, str *argv)
#ifndef CAMU_SINK_ONLY
bool local = argc > 1;
+#else
+ if (argc > 1) {
+ warn("Got arguments in a sink-only configuration.");
+ }
#endif
u8 type;
@@ -167,7 +172,6 @@ s32 window_system_main(s32 argc, str *argv)
if (local) {
c.desktop.exit_callback = exit_callback;
c.desktop.userdata = &c;
- c.desktop.sink.local_server = &c.server.data.server;
}
#endif
if (!camu_desktop_connect(&c.desktop, type, &c.loop, &addr, CAMU_PORT)) {
@@ -199,9 +203,6 @@ s32 window_system_main(s32 argc, str *argv)
nn_packet_free(packet);
}
}
-#else
- (void)argc;
- (void)argv;
#endif
struct nn_thread thread0;
@@ -247,7 +248,7 @@ s32 main(s32 argc, char *cargv[])
str arg;
#ifdef NAUNET_ON_WINDOWS
if (!al_str_from_wstr(&arg, &al_wstr_cr(wargv[i]))) {
- al_log_error("cmv", "Failed to parse argument #%i.", i);
+ error("Failed to parse argument #%i.", i);
continue;
}
#else
diff --git a/src/fruits/ctv/ctv.c b/src/fruits/ctv/ctv.c
index c3af943..452cd39 100644
--- a/src/fruits/ctv/ctv.c
+++ b/src/fruits/ctv/ctv.c
@@ -1,5 +1,5 @@
-#include <stl/platform.h>
#include <al/log.h>
+#include <android/log.h>
#include "../../libsink/sink.h"
#include "../../sink/desktop.h"
diff --git a/src/liana/list.c b/src/liana/list.c
index 47b8545..3e2a350 100644
--- a/src/liana/list.c
+++ b/src/liana/list.c
@@ -1,9 +1,9 @@
-#include <nnwt/thread.h>
-#include <al/random.h>
-#include <al/lib.h>
#define AL_LOG_SECTION "list"
//#define AL_LOG_ENABLE_TRACE
#include <al/log.h>
+#include <al/lib.h>
+#include <al/random.h>
+#include <nnwt/thread.h>
#include "list.h"
#include "list_cmp.h"
@@ -269,27 +269,12 @@ static s32 get_sequence_from_entry_id(struct lia_list *list, u32 id)
return -1;
}
-static struct lia_list_entry *get_entry_from_id(struct lia_list *list, u32 id, s32 *sequence)
-{
- struct lia_list_entry *entry;
- al_array_foreach(list->entries, i, entry) {
- if (entry->id == id) {
- *sequence = (s32)i;
- return entry;
- }
- }
- return NULL;
-}
-
static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
{
- if (index == list->current) return true;
if (sequence == LIANA_SEQUENCE_ANY) sequence = list->current;
if (sequence < 0) return true; // list->current = -1
if (sequence != list->current) {
- // Skipping from an entry other than current is not handled and will cause very
- // confusing errors. To handle it wouldn't make sense anyway because the outcome
- // would likely be unexpected to the user.
+ warn("Discarding out of date skip().");
return true;
}
@@ -383,20 +368,16 @@ static bool handle_skipto(struct lia_list *list, s32 sequence, s32 index)
static bool handle_skip(struct lia_list *list, s32 sequence, s32 n)
{
if (sequence == LIANA_SEQUENCE_ANY) sequence = list->current;
- struct lia_list_cmd *cmd = list->cmd;
- cmd->op = SKIPTO;
- cmd->sequence = sequence;
- cmd->arg0.i = sequence + n;
- return handle_skipto(list, cmd->sequence, cmd->arg0.i);
+ if (sequence < 0) return true; // list->current = -1
+ return handle_skipto(list, sequence, sequence + n);
}
static void handle_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
{
- // pts should be treated as a hint.
if (sequence == LIANA_SEQUENCE_ANY) sequence = list->current;
if (sequence < 0) return; // list->current = -1
if (sequence != list->current) {
- // A non-current entry should always be paused.
+ warn("Discarding out of date toggle_pause().");
return;
}
@@ -404,7 +385,7 @@ static void handle_toggle_pause(struct lia_list *list, s32 sequence, f64 pts)
al_assert(entry && !entry->held);
u64 now = nn_get_timestamp();
- u8 pause = entry->paused_at == LIANA_TIMESTAMP_INVALID ? LIANA_PAUSE_PAUSE : LIANA_PAUSE_RESUME;
+ 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;
@@ -463,7 +444,7 @@ static void handle_seek(struct lia_list *list, s32 sequence, u32 id, u64 pos)
pos = CLAMP(pos, (u64)0, entry->duration);
u64 now = nn_get_timestamp();
u64 at = now + LIANA_BASE_DELAY;
- u8 pause = entry->paused_at == LIANA_TIMESTAMP_INVALID ? LIANA_PAUSE_RESUME : LIANA_PAUSE_NONE;
+ u8 pause = (entry->paused_at == LIANA_TIMESTAMP_INVALID) ? LIANA_PAUSE_RESUME : LIANA_PAUSE_NONE;
entry->ended = false;
entry->reset_id = get_incremental_id(list);
@@ -520,9 +501,9 @@ static bool handle_end(struct lia_list *list, u32 id, u32 reset_id)
cmd->op = SEEK;
cmd->sequence = sequence;
cmd->arg0.u = id;
- cmd->argf = 0.0;
- pump_queue(list);
- return false;
+ cmd->arg1.u = 0;
+ handle_seek(list, cmd->sequence, cmd->arg0.u, cmd->arg1.u);
+ return true;
#endif
s32 size = (s32)list->entries.count;
@@ -543,8 +524,7 @@ static bool handle_end(struct lia_list *list, u32 id, u32 reset_id)
cmd->op = SKIPTO;
cmd->sequence = sequence;
cmd->arg0.i = next;
- pump_queue(list);
- return false;
+ return handle_skipto(list, cmd->sequence, cmd->arg0.i);
} else {
list->idle = true;
}
@@ -570,59 +550,52 @@ static bool adjust_current(struct lia_list *list, struct lia_list_entry *previou
break;
}
}
- al_assert(cmd->op == SKIPTO && entry && !entry->held);
- pump_queue(list);
- return false;
+ al_assert(entry && cmd->op == SKIPTO);
+ return handle_skipto(list, cmd->sequence, cmd->arg0.i);
}
static bool handle_reverse(struct lia_list *list)
{
if (list->current < 0) return true;
-
struct lia_list_entry *previous = al_array_at(list->entries, list->current);
-
u32 size = list->entries.count;
for (u32 i = 0; i < size; i++) {
u32 tail = size - (i + 1);
if (tail <= i) break;
SWAP(al_array_at(list->entries, i), al_array_at(list->entries, tail));
}
-
return adjust_current(list, previous);
}
static bool handle_sort(struct lia_list *list)
{
if (list->current < 0) return true;
-
struct lia_list_entry *previous = al_array_at(list->entries, list->current);
-
al_array_sort(list->entries, struct lia_list_entry *, camu_db_compare);
-
return adjust_current(list, previous);
}
static bool handle_shuffle(struct lia_list *list)
{
if (list->current < 0) return true;
-
u32 size = list->entries.count;
if (size <= 1) return false;
-
struct lia_list_entry *previous = al_array_at(list->entries, list->current);
-
/* https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
for i from 0 to nāˆ’2 do
j ← random integer such that i ≤ j ≤ n-1
exchange a[i] and a[j]
*/
- // Changed size - 2 to size - 1 to support 2 entry lists.
- // I assume that alters the algorithm, not sure how badly.
- for (u32 i = 0; i < size - 1; i++) {
- u32 j = i + (al_rand() % (size - i));
- SWAP(al_array_at(list->entries, i), al_array_at(list->entries, j));
+ if (size == 2) {
+ if (al_rand() % 2) {
+ SWAP(al_array_at(list->entries, 0), al_array_at(list->entries, 1));
+ }
+ } else {
+ for (u32 i = 0; i < size - 2; i++) {
+ u32 j = i + (al_rand() % (size - i));
+ SWAP(al_array_at(list->entries, i), al_array_at(list->entries, j));
+ }
}
-
return adjust_current(list, previous);
}
@@ -642,10 +615,12 @@ static void handle_unset(struct lia_list *list)
static void run_queue(struct lia_list *list)
{
- // @TODO: What does current = -1/currentless really mean.
if (!list->cmd) {
- if (!list->command_queue.count) return;
- al_array_pop_at(list->command_queue, 0, list->cmd);
+ if (list->command_queue.count) {
+ al_array_pop_at(list->command_queue, 0, list->cmd);
+ } else {
+ return;
+ }
}
struct lia_list_cmd *cmd = list->cmd;
switch (cmd->op) {
@@ -662,15 +637,14 @@ static void run_queue(struct lia_list *list)
return;
}
break;
+ // Return on SKIPTO/SKIP: Target entry not loaded.
case SKIPTO:
if (!handle_skipto(list, cmd->sequence, cmd->arg0.i)) {
- // Target entry not loaded.
return;
}
break;
case SKIP:
if (!handle_skip(list, cmd->sequence, cmd->arg0.i)) {
- // Converted to skipto and target entry not loaded.
return;
}
break;
@@ -682,10 +656,11 @@ static void run_queue(struct lia_list *list)
break;
case END:
if (!handle_end(list, cmd->arg0.u, cmd->arg1.u)) {
- // End was converted to a skip.
+ // Converted to a SKIP and target entry not loaded.
return;
}
break;
+ // Return on order change: Converted to SKIPTO and new current not loaded.
case REVERSE:
if (!handle_reverse(list)) {
return;
@@ -764,9 +739,9 @@ void lia_list_add(struct lia_list *list, void *opaque, u64 duration, wstr *name)
pump_queue(list);
}
-
void lia_list_skipto(struct lia_list *list, s32 sequence, s32 index)
{
+ if (sequence == index || index < 0) return;
struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
cmd->op = SKIPTO;
cmd->sequence = sequence;
@@ -777,6 +752,7 @@ void lia_list_skipto(struct lia_list *list, s32 sequence, s32 index)
void lia_list_skip(struct lia_list *list, s32 sequence, s32 n)
{
+ if (n == 0) return;
struct lia_list_cmd *cmd = al_alloc_object(struct lia_list_cmd);
cmd->op = SKIP;
cmd->sequence = sequence;
@@ -875,20 +851,17 @@ void lia_list_free(struct lia_list *list)
}
al_array_free(list->command_queue);
if (list->cmd) al_free(list->cmd);
-
struct lia_list_entry *entry;
al_array_foreach(list->entries, i, entry) {
al_wstr_free(&entry->name);
al_free(entry);
}
al_array_free(list->entries);
-
struct lia_list_sink *sink;
al_array_foreach(list->sinks, i, sink) {
al_free(sink);
}
al_array_free(list->sinks);
-
al_str_free(&list->name);
}
@@ -929,7 +902,7 @@ static void set_queued(struct lia_list *list)
}
queued->start = current->start + (current->duration - current->offset);
- u8 pause = queued->paused_at == LIANA_TIMESTAMP_INVALID ? LIANA_PAUSE_RESUME : LIANA_PAUSE_NONE;
+ u8 pause = (queued->paused_at == LIANA_TIMESTAMP_INVALID) ? LIANA_PAUSE_RESUME : LIANA_PAUSE_NONE;
struct lia_timing time = {
.at = queued->start,
.seek_pos = queued->offset,
diff --git a/src/liana/server.c b/src/liana/server.c
index 9d3661c..808f810 100644
--- a/src/liana/server.c
+++ b/src/liana/server.c
@@ -47,7 +47,7 @@ static void packet_pool_callback(void *userdata, struct nn_packet *packet)
{
struct lia_node_connection *conn = (struct lia_node_connection *)userdata;
if (!nn_packet_stream_send_packet(conn->stream, packet)) {
- data_packet_sent_callback(conn, packet);
+ nn_packet_pool_return(&conn->pool, packet);
}
}
diff --git a/src/libsink/sink.c b/src/libsink/sink.c
index e5f9351..d3647f1 100644
--- a/src/libsink/sink.c
+++ b/src/libsink/sink.c
@@ -60,9 +60,9 @@ enum {
#define ENTRY_MAX_AGE 3
// printf format for entries.
-#if defined C89ATOMIC_64BIT
+#if defined AL_WE_64BIT
#define ENTRY_FMT "#%u(0x%llx)"
-#elif defined C89ATOMIC_32BIT
+#elif defined AL_WE_32BIT
#define ENTRY_FMT "#%u(0x%lx)"
#endif
#define ENTRY_ARG(entry) \
@@ -76,16 +76,16 @@ enum {
#define AUDIO_EMPTY(entry) BUFFER_EMPTY(&(entry)->audio)
#define VIDEO_EMPTY(entry) BUFFER_EMPTY(&(entry)->video)
+#define AUDIO_NOT_ADDED(entry) ((entry)->audio.state != BUFFER_ADDED)
+#define VIDEO_NOT_ADDED(entry) ((entry)->video.state != BUFFER_ADDED)
+
#define AUDIO_ADDED_OR_EMPTY(entry) ((entry)->audio.state == BUFFER_ADDED || BUFFER_EMPTY(&(entry)->audio))
#define VIDEO_ADDED_OR_EMPTY(entry) ((entry)->video.state == BUFFER_ADDED || BUFFER_EMPTY(&(entry)->video))
#define AUDIO_ENDED_OR_EMPTY(entry) ((entry)->audio.state == BUFFER_ENDED || BUFFER_EMPTY(&(entry)->audio))
#define VIDEO_ENDED_OR_EMPTY(entry) ((entry)->video.state == BUFFER_ENDED || BUFFER_EMPTY(&(entry)->video))
-#define AUDIO_NOT_ADDED(entry) ((entry)->audio.state != BUFFER_ADDED)
-#define VIDEO_NOT_ADDED(entry) ((entry)->video.state != BUFFER_ADDED)
-
-#define VIDEO_IS_SINGLE_FRAME(entry) camu_video_buffer_is_single_frame(&(entry)->video.buf)
+#define VIDEO_IS_SINGLE_FRAME(entry) (entry)->video.buf.single_frame
#if defined CAMU_SCREEN_THREADED && defined CAMU_MIXER_THREADED
#define BLOCKING_SLEEP(delay) nn_thread_sleep(delay)
@@ -126,6 +126,8 @@ static void request_video_refresh(struct camu_sink *sink)
{
#ifndef CAMU_SINK_NO_VIDEO
sink->callback(sink->userdata, CAMU_SINK_REFRESH_VIDEO, 0, NULL);
+#else
+ (void)sink;
#endif
}
@@ -148,16 +150,19 @@ static inline void add_entry_video_buffer(struct camu_sink_entry *entry)
#ifndef CAMU_SINK_NO_VIDEO
struct camu_sink *sink = entry->sink;
sink->callback(sink->userdata, CAMU_SINK_ADD_BUFFER, CAMU_SINK_VIDEO, &entry->video.buf);
+#else
+ (void)entry;
#endif
}
-static void remove_entry_audio_buffer(struct camu_sink *sink, struct camu_sink_entry *entry)
+static void remove_entry_audio_buffer(struct camu_sink_entry *entry)
{
al_assert(AUDIO_STATE(entry) != BUFFER_ENDED);
al_assert(AUDIO_STATE(entry) != BUFFER_INIT);
switch (AUDIO_STATE(entry)) {
case BUFFER_ADDED:
AUDIO_STATE(entry) = BUFFER_SET_OR_BUFFERED;
+ struct camu_sink *sink = entry->sink;
#ifdef CAMU_MIXER_THREADED_START_STOP
sink->callback(sink->userdata, CAMU_SINK_REMOVE_BUFFER, CAMU_SINK_AUDIO, &entry->audio.buf);
#else
@@ -177,7 +182,7 @@ static void remove_entry_audio_buffer(struct camu_sink *sink, struct camu_sink_e
}
}
-static void remove_entry_video_buffer(struct camu_sink *sink, struct camu_sink_entry *entry)
+static void remove_entry_video_buffer(struct camu_sink_entry *entry)
{
// Don't assert !entry->ended here because of single frame handling.
al_assert(VIDEO_STATE(entry) != BUFFER_ENDED);
@@ -186,6 +191,7 @@ static void remove_entry_video_buffer(struct camu_sink *sink, struct camu_sink_e
case BUFFER_ADDED:
VIDEO_STATE(entry) = BUFFER_SET_OR_BUFFERED;
#ifndef CAMU_SINK_NO_VIDEO
+ struct camu_sink *sink = entry->sink;
sink->callback(sink->userdata, CAMU_SINK_REMOVE_BUFFER, CAMU_SINK_VIDEO, &entry->video.buf);
#endif
break;
@@ -202,16 +208,15 @@ static void remove_entry_video_buffer(struct camu_sink *sink, struct camu_sink_e
// It's possible for some of an entries buffers to be ENDED while others are still
// ADDED and playing. We handle that by making remove_entry_buffers() and
// add_audio/video_if_set_and_buffered() no-ops for ENDED buffers.
-static void remove_entry_buffers(struct camu_sink *sink, struct camu_sink_entry *entry)
+static void remove_entry_buffers(struct camu_sink_entry *entry)
{
- trace("remove_entry_buffers("ENTRY_FMT"), audio_state: %hhu, video_state: %hhu.",
- ENTRY_ARG(entry), AUDIO_STATE(entry), VIDEO_STATE(entry));
+ trace("remove_entry_buffers("ENTRY_FMT"), audio_state: %hhu, video_state: %hhu.", ENTRY_ARG(entry), AUDIO_STATE(entry), VIDEO_STATE(entry));
al_assert(!entry->ended);
if (AUDIO_STATE(entry) != BUFFER_ENDED) {
- remove_entry_audio_buffer(sink, entry);
+ remove_entry_audio_buffer(entry);
}
if (VIDEO_STATE(entry) != BUFFER_ENDED) {
- remove_entry_video_buffer(sink, entry);
+ remove_entry_video_buffer(entry);
}
}
@@ -278,12 +283,9 @@ static inline s32 get_sequence_for_command(struct camu_sink *sink)
{
// SEQUENCE_ANY resolves order on the server.
s32 sequence = LIANA_SEQUENCE_ANY;
-#if 0
- // Setting an explicit sequence makes skip and pause act on "what you see".
- // This is unlikely to be expected behavior in the common case. The user might
- // feel like their input was eaten if skipping after a different skip happens
- // on the server but is yet to be reflected on their end.
- if (sink->target) {
+ // If we're local this could only lead to feeling like your inputs were eaten.
+#ifndef CAMU_SINK_LOCAL
+ if (sink->target && sink->target != (struct camu_sink_entry *)0xb00b) {
sequence = sink->target->sequence;
} else if (sink->current) {
sequence = sink->current->sequence;
@@ -463,14 +465,16 @@ static void queue_signal_callback(void *userdata)
static void mixer_callback(void *userdata, u8 op)
{
+ struct camu_sink *sink = (struct camu_sink *)userdata;
if (op == CAMU_MIXER_EMPTY) {
info("Mixer empty.");
#ifndef LIANA_LIST_SCUFFED_LOOP
- struct camu_sink *sink = (struct camu_sink *)userdata;
queue_cmd(sink, (struct camu_sink_cmd){
.op = STOP,
.value.i = CAMU_SINK_AUDIO
});
+#else
+ (void)sink;
#endif
}
}
@@ -548,7 +552,7 @@ static void maybe_remove_previous(struct camu_sink *sink)
trace("maybe_remove_previous(), previous_count: %u.", sink->previous.count);
struct camu_sink_entry *previous;
al_array_foreach(sink->previous, i, previous) {
- remove_entry_buffers(sink, previous);
+ remove_entry_buffers(previous);
}
sink->previous.count = 0;
}
@@ -577,14 +581,13 @@ static void maybe_remove_from_previous(struct camu_sink *sink, struct camu_sink_
static void maybe_add_to_previous(struct camu_sink *sink, struct camu_sink_entry *previous,
struct camu_sink_entry *target)
{
- trace("maybe_add_to_previous("ENTRY_FMT"), "ENTRY_FMT"), audio_state: %hhu, video_state: %hhu.",
- ENTRY_ARG(previous), ENTRY_ARG(target), AUDIO_STATE(previous), VIDEO_STATE(previous));
+ trace("maybe_add_to_previous("ENTRY_FMT", "ENTRY_FMT"), audio_state: %hhu, video_state: %hhu.", ENTRY_ARG(previous), ENTRY_ARG(target), AUDIO_STATE(previous), VIDEO_STATE(previous));
al_assert(previous != target);
al_assert(!previous->ended);
// If none of the entry's buffers are added, we don't care about adding it to previous.
bool dangling_target = target == (struct camu_sink_entry *)0xb00b;
if (dangling_target || target->ended || !(AUDIO_STATE(previous) == BUFFER_ADDED || VIDEO_STATE(previous) == BUFFER_ADDED)) {
- remove_entry_buffers(sink, previous);
+ remove_entry_buffers(previous);
return;
}
al_array_push(sink->previous, previous);
@@ -602,7 +605,7 @@ static void do_add_entry(struct camu_sink_entry *entry)
}
maybe_remove_previous(entry->sink);
queue_cmd(entry->sink, (struct camu_sink_cmd){
- .op = VIDEO_EMPTY(entry) || VIDEO_IS_SINGLE_FRAME(entry) || entry->paused ? STOP : START,
+ .op = (VIDEO_EMPTY(entry) || VIDEO_IS_SINGLE_FRAME(entry) || entry->paused) ? STOP : START,
.value.i = CAMU_SINK_VIDEO
});
if (VIDEO_EMPTY(entry)) {
@@ -610,7 +613,7 @@ static void do_add_entry(struct camu_sink_entry *entry)
request_video_refresh(entry->sink);
}
queue_cmd(entry->sink, (struct camu_sink_cmd){
- .op = AUDIO_EMPTY(entry) || entry->paused ? STOP : START,
+ .op = (AUDIO_EMPTY(entry) || entry->paused) ? STOP : START,
.value.i = CAMU_SINK_AUDIO
});
}
@@ -650,9 +653,7 @@ void add_video_if_set_and_buffered(struct camu_sink_entry *entry)
VIDEO_STATE(entry) = BUFFER_SET_OR_BUFFERED;
} else if (VIDEO_STATE(entry) == BUFFER_SET_OR_BUFFERED) {
VIDEO_STATE(entry) = BUFFER_ADDED;
- if (VIDEO_IS_SINGLE_FRAME(entry)) {
- add_entry_video_buffer(entry);
- }
+ if (VIDEO_IS_SINGLE_FRAME(entry)) add_entry_video_buffer(entry);
if (AUDIO_ADDED_OR_EMPTY(entry)) {
do_add_entry(entry);
}
@@ -661,8 +662,7 @@ void add_video_if_set_and_buffered(struct camu_sink_entry *entry)
static void switch_to(struct camu_sink *sink, struct camu_sink_entry *target)
{
- trace("switch_to("ENTRY_FMT"), current: "ENTRY_FMT".",
- ENTRY_ARG(target), ENTRY_ARG(sink->current));
+ trace("switch_to("ENTRY_FMT"), current: "ENTRY_FMT".", ENTRY_ARG(target), ENTRY_ARG(sink->current));
if (sink->current) {
struct camu_sink_entry *current = sink->current;
@@ -677,7 +677,7 @@ static void switch_to(struct camu_sink *sink, struct camu_sink_entry *target)
}
if (ensure_removed) {
if (VIDEO_IS_SINGLE_FRAME(current)) {
- remove_entry_video_buffer(sink, current);
+ remove_entry_video_buffer(current);
}
al_assert(AUDIO_NOT_ADDED(current));
al_assert(VIDEO_NOT_ADDED(current));
@@ -719,8 +719,7 @@ static void switch_to(struct camu_sink *sink, struct camu_sink_entry *target)
static void pause_and_swap_to(struct camu_sink *sink, struct camu_sink_entry *target, u64 at)
{
struct camu_sink_entry *current = sink->current;
- trace("pause_and_swap_to("ENTRY_FMT"), %llu), current: "ENTRY_FMT".",
- ENTRY_ARG(target), at, ENTRY_ARG(current));
+ trace("pause_and_swap_to("ENTRY_FMT"), current: "ENTRY_FMT".", ENTRY_ARG(target), ENTRY_ARG(current));
al_assert(target != current);
if (!current || current->ended) {
switch_to(sink, target);
@@ -797,7 +796,7 @@ static void audio_buffer_callback(void *userdata, u8 op)
// Getting EOF on a buffer that isn't ADDED is very possible if the audio
// output is threaded. Even more if we had to wait on the lock above.
if (AUDIO_STATE(entry) == BUFFER_ADDED) {
- remove_entry_audio_buffer(sink, entry);
+ remove_entry_audio_buffer(entry);
}
// This assert likely doesn't matter due to the handling of the ENDED state.
al_assert(AUDIO_STATE(entry) == BUFFER_SET_OR_BUFFERED);
@@ -846,7 +845,7 @@ static void video_buffer_callback(void *userdata, u8 op)
}
if (!single_frame) {
if (VIDEO_STATE(entry) == BUFFER_ADDED) {
- remove_entry_video_buffer(sink, entry);
+ remove_entry_video_buffer(entry);
}
al_assert(VIDEO_STATE(entry) == BUFFER_SET_OR_BUFFERED);
VIDEO_STATE(entry) = BUFFER_ENDED;
@@ -879,8 +878,7 @@ static void clock_callback(void *userdata, u8 op)
struct camu_sink *sink = entry->sink;
if (op == CAMU_CLOCK_PAUSED) {
nn_mutex_lock(&sink->lock);
- trace("clock_callback(CAMU_CLOCK_PAUSED, "ENTRY_FMT"), target: "ENTRY_FMT".",
- ENTRY_ARG(entry), ENTRY_ARG(sink->target));
+ trace("clock_paused("ENTRY_FMT"), target: "ENTRY_FMT".", ENTRY_ARG(entry), ENTRY_ARG(sink->target));
if (entry == sink->current) {
if (sink->target) {
switch_to(sink, sink->target);
@@ -1040,8 +1038,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
nn_mutex_lock(&sink->lock);
- trace("remove_buffers("ENTRY_FMT", %s), entry == current: %s.",
- ENTRY_ARG(entry), BOOLSTR(reconnect), BOOLSTR(entry == sink->current));
+ trace("remove_buffers("ENTRY_FMT", %s), entry == current: %s.", ENTRY_ARG(entry), BOOLSTR(reconnect), BOOLSTR(entry == sink->current));
if (reconnect && entry == sink->current) {
sink->reconnecting = entry;
@@ -1053,11 +1050,11 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
remove_previous_if_contains(sink, entry);
if (AUDIO_STATE(entry) == BUFFER_ADDED) {
- remove_entry_audio_buffer(sink, entry);
+ remove_entry_audio_buffer(entry);
}
bool ignore_video = reconnect && VIDEO_IS_SINGLE_FRAME(entry);
if (!ignore_video && VIDEO_STATE(entry) == BUFFER_ADDED) {
- remove_entry_video_buffer(sink, entry);
+ remove_entry_video_buffer(entry);
}
// Resolve any queued REMOVE_BUFFER requests before blocking.
@@ -1107,8 +1104,10 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
}
case LIANA_CLIENT_RESUME_AT: {
struct lia_timing *time = (struct lia_timing *)opaque;
- trace("resume_at("ENTRY_FMT"), %llu, %llu), paused_at: %f.",
- ENTRY_ARG(entry), time->seek_pos, time->at, entry->clock.paused_at);
+ trace("resume_at("ENTRY_FMT"), paused_at: %f.", ENTRY_ARG(entry), entry->clock.paused_at);
+#ifdef CAMU_SINK_LOCAL
+ time->at = 0;
+#endif
nn_mutex_lock(&sink->lock);
#if defined LIANA_LIST_SCUFFED_LOOP
if (time->seek_pos == 0) {
@@ -1125,8 +1124,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
case LIANA_CLIENT_RECONNECTED: {
bool unconfigured = *(bool *)opaque;
nn_mutex_lock(&sink->lock);
- trace("reconnected("ENTRY_FMT"), reconnecting: "ENTRY_FMT".",
- ENTRY_ARG(entry), ENTRY_ARG(sink->reconnecting));
+ trace("reconnected("ENTRY_FMT"), reconnecting: "ENTRY_FMT".", ENTRY_ARG(entry), ENTRY_ARG(sink->reconnecting));
if (entry == sink->reconnecting) {
al_assert(entry == sink->current);
if (AUDIO_STATE(entry) > BUFFER_QUEUED) {
@@ -1172,7 +1170,7 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
if (VIDEO_STATE(entry) == BUFFER_ADDED) {
al_assert(VIDEO_IS_SINGLE_FRAME(entry));
- remove_entry_video_buffer(sink, entry);
+ remove_entry_video_buffer(entry);
while (entry_video_buffer_held(entry)) { BLOCKING_SLEEP(NNWT_TS_FROM_USEC(2000)); }
}
@@ -1220,6 +1218,17 @@ static void client_callback(void *userdata, u8 op, struct camu_codec_stream *str
}
}
+static const char *pause_op_name(u8 pause)
+{
+ switch (pause) {
+ case LIANA_PAUSE_NONE: return "PAUSE_NONE";
+ case LIANA_PAUSE_RESUME: return "PAUSE_RESUME";
+ case LIANA_PAUSE_PAUSE: return "PAUSE_PAUSE";
+ case LIANA_PAUSE_BOTH: return "PAUSE_BOTH";
+ default: al_assert_and_return(NULL);
+ };
+}
+
static struct camu_sink_entry *create_entry(struct camu_sink *sink, u32 id)
{
struct camu_sink_entry *entry = al_alloc_object(struct camu_sink_entry);
@@ -1242,9 +1251,9 @@ static struct camu_sink_entry *create_entry(struct camu_sink *sink, u32 id)
entry->video.buf.callback = video_buffer_callback;
entry->video.buf.userdata = entry;
- entry->client.renderer = sink->video.renderer;
entry->client.callback = client_callback;
entry->client.userdata = entry;
+ entry->client.renderer = sink->video.renderer;
entry->client.prefs = sink->prefs;
al_array_push(sink->entries, entry);
@@ -1298,14 +1307,11 @@ static bool set_command_callback(void *userdata, struct nn_rpc_connection *conn,
u32 reset_id = nn_packet_read_u32(packet);
struct camu_sink_entry *current = sink->current;
- struct camu_sink_entry *prev_target = sink->target;
struct camu_sink_entry *entry = get_entry_from_id(sink, id);
bool create = !entry;
- if (create) {
- entry = create_entry(sink, id);
- }
+ if (create) entry = create_entry(sink, id);
entry->sequence = sequence;
- sink->lru = al_u16_inc_wrap(sink->lru);
+ sink->lru = al_u16_add_wrap(sink->lru, SINK_LRU_MAX);
entry->lru = sink->lru;
entry->reset_id = reset_id;
@@ -1322,9 +1328,6 @@ static bool set_command_callback(void *userdata, struct nn_rpc_connection *conn,
lia_client_connect(&entry->client, sink->loop, sink->type, &addr, port, node_id, seek_pos);
}
- trace("set("ENTRY_FMT", %llu), created: %s, pause: %hhu, current: "ENTRY_FMT", target: "ENTRY_FMT".",
- ENTRY_ARG(entry), at, BOOLSTR(create), pause, ENTRY_ARG(current), ENTRY_ARG(prev_target));
-
if (op == LIANA_SINK_BUFFER) {
goto out;
} else if (op == LIANA_SINK_BUFFER_AND_QUEUE) {
@@ -1340,7 +1343,9 @@ static bool set_command_callback(void *userdata, struct nn_rpc_connection *conn,
}
#ifdef CAMU_SINK_LOCAL
+ (void)at;
al_assert(entry != current);
+ trace("set("ENTRY_FMT"), %s[local], created: %s.", ENTRY_ARG(entry), pause_op_name(pause), BOOLSTR(create));
if (current && !current->ended) {
current->audio.ignore_paused = true;
if (!current->paused) {
@@ -1356,6 +1361,8 @@ static bool set_command_callback(void *userdata, struct nn_rpc_connection *conn,
switch_to(sink, entry);
#else
// For target to be set that must mean current is set, armed to pause, and not ended.
+ struct camu_sink_entry *prev_target = sink->target;
+ trace("set("ENTRY_FMT"), %s, created: %s, target: "ENTRY_FMT".", ENTRY_ARG(entry), pause_op_name(pause), BOOLSTR(create), ENTRY_ARG(prev_target));
switch (pause) {
case LIANA_PAUSE_NONE:
if (prev_target) {
@@ -1446,13 +1453,10 @@ static bool pause_command_callback(void *userdata, struct nn_rpc_connection *con
struct camu_sink_entry *entry = get_entry_from_id(sink, id);
if (!entry) goto out;
al_assert(entry->sequence == sequence);
-
nn_mutex_lock(&sink->lock);
-
- trace("pause("ENTRY_FMT", %llu), pause: %hhu, audio_state: %hhu, video_state: %hhu.",
- ENTRY_ARG(entry), at, pause, AUDIO_STATE(entry), VIDEO_STATE(entry));
-
+ trace("pause("ENTRY_FMT"), %s, audio_state: %hhu, video_state: %hhu.", ENTRY_ARG(entry), pause_op_name(pause), AUDIO_STATE(entry), VIDEO_STATE(entry));
#ifdef CAMU_SINK_LOCAL
+ (void)at;
sink_local_pause(sink, entry);
#else
switch (pause) {
@@ -1481,7 +1485,6 @@ static bool pause_command_callback(void *userdata, struct nn_rpc_connection *con
break;
}
#endif
-
nn_mutex_unlock(&sink->lock);
out:
@@ -1505,13 +1508,8 @@ static bool seek_command_callback(void *userdata, struct nn_rpc_connection *conn
struct camu_sink_entry *entry = get_entry_from_id(sink, id);
if (!entry) goto out;
- entry->reset_id = reset_id;
-
trace("seek("ENTRY_FMT"), reset_id: %u.", ENTRY_ARG(entry), reset_id);
-
-#ifdef CAMU_SINK_LOCAL
- at = 0;
-#endif
+ entry->reset_id = reset_id;
// The rest of the seek is handled in client_callback()'s.
lia_client_seek(&entry->client, pos, at);
@@ -1630,7 +1628,7 @@ void camu_sink_seek(struct camu_sink *sink, void *value, u8 mode)
{
nn_mutex_lock(&sink->lock);
struct camu_sink_entry *current = sink->current;
- u64 duration;
+ u64 duration = 0;
if (current) duration = current->client.duration;
f64 pts = camu_clock_get_last_pts(&current->clock);
nn_mutex_unlock(&sink->lock);
diff --git a/src/libsink/sink.h b/src/libsink/sink.h
index 32fdc26..d1bcd26 100644
--- a/src/libsink/sink.h
+++ b/src/libsink/sink.h
@@ -7,7 +7,7 @@
#include <nnwt/timer.h>
#include "../util/queue.h"
-
+#include "../liana/client.h"
#include "../buffer/clock.h"
#include "../buffer/audio.h"
#ifndef CAMU_SINK_NO_VIDEO
@@ -16,8 +16,6 @@
#include "../buffer/video_null.h"
#endif
-#include "../liana/client.h"
-
enum {
CAMU_SINK_AUDIO = 0,
CAMU_SINK_VIDEO
@@ -56,7 +54,7 @@ struct camu_sink_entry {
bool paused;
struct {
u8 state;
- // Don't stop the audio output when this entry is paused.
+ // Don't stop the audio output on BUFFER_PAUSED from this entry.
bool ignore_paused;
struct camu_audio_buffer buf;
struct lia_vcr_track *track;
@@ -87,7 +85,6 @@ struct camu_sink {
struct nn_timer reconnect_timer;
struct nn_signal queue_signal;
queue(struct camu_sink_cmd) queue;
- str default_list;
struct camu_sink_entry *current;
struct camu_sink_entry *queued;
struct camu_sink_entry *target;
@@ -104,7 +101,7 @@ struct camu_sink {
struct camu_renderer *renderer;
} video;
struct lia_prefs prefs;
- struct lia_server *local_server;
+ str default_list;
u8 (*callback)(void *, u8, u8, void *);
void *userdata;
};
diff --git a/src/screen/screen.c b/src/screen/screen.c
index ed4345d..e35cfa0 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -148,7 +148,7 @@ static bool scroll_callback(void *userdata, f64 y)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
if (SCREEN_MOD1(scr)) {
- f32 change = y < 0.0 ? 0.025 : -0.025;
+ f32 change = (y < 0.0) ? 0.025 : -0.025;
scr->callback(scr->userdata, CAMU_SCREEN_OFFSET_VOLUME, &change);
} else {
// This sucks.
@@ -342,10 +342,10 @@ static void key_immediate_callback(void *userdata, u8 state, u16 button)
}
}
-bool camu_screen_init(struct camu_screen *scr, void *context)
+bool camu_screen_init(struct camu_screen *scr)
{
al_atomic_store(s32)(&scr->state, CAMU_SCREEN_PAUSED, AL_ATOMIC_RELAXED);
- scr->window = stl_window_create(context);
+ scr->window = stl_window_create();
scr->window->render_callback = render_callback;
scr->window->refresh_callback = refresh_callback;
scr->window->pointer_pos_callback = pointer_pos_callback;
diff --git a/src/screen/screen.h b/src/screen/screen.h
index d79d977..bf1f519 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -77,7 +77,7 @@ struct camu_screen {
void *userdata;
};
-bool camu_screen_init(struct camu_screen *scr, void *context);
+bool camu_screen_init(struct camu_screen *scr);
bool camu_screen_create_window(struct camu_screen *scr, const char *name);
bool camu_screen_create_renderer(struct camu_screen *scr, struct camu_renderer *renderer);
void camu_screen_add_buffer(struct camu_screen *scr, struct camu_video_buffer *buf);
diff --git a/src/sink/desktop.c b/src/sink/desktop.c
index 6632827..7803982 100644
--- a/src/sink/desktop.c
+++ b/src/sink/desktop.c
@@ -25,10 +25,6 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
struct camu_mixer *mixer = &c->mixer;
struct camu_screen *scr = &c->scr;
switch (op) {
- case CAMU_SINK_MOCK_CLOSE:
- c->should_quit = 1;
- camu_screen_wake(&c->scr);
- break;
case CAMU_SINK_ADD_BUFFER:
switch (type) {
case CAMU_SINK_AUDIO: {
@@ -99,11 +95,16 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
break;
}
break;
+ case CAMU_SINK_MOCK_CLOSE:
+ c->should_quit = 1;
+ camu_screen_wake(&c->scr);
+ break;
case CAMU_SINK_EXIT:
camu_sink_close(&c->sink);
if (c->exit_callback) {
c->exit_callback(c->userdata, c);
}
+ break;
}
return CAMU_SINK_OK;
}
@@ -204,7 +205,7 @@ bool camu_desktop_init(struct camu_desktop *c, const char *name)
{
c->scr.callback = screen_callback;
c->scr.userdata = c;
- if (!camu_screen_init(&c->scr, NULL) || !camu_screen_create_window(&c->scr, name)) {
+ if (!camu_screen_init(&c->scr) || !camu_screen_create_window(&c->scr, name)) {
return false;
}
#if defined CAMU_RENDERER_TIGER