From 191d98d306d48ba36d5a5a2eb3583b805a03b2c3 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Tue, 18 Mar 2025 10:56:12 -0400 Subject: Cleanup Signed-off-by: Andrew Opalach --- src/buffer/audio.c | 70 ++++++++------------ src/buffer/video.c | 18 ++---- src/buffer/video.h | 1 - src/buffer/video_null.h | 8 +-- src/cache/backings/file.c | 4 +- src/cache/backings/file.h | 2 +- src/cache/backings/file_common.c | 24 ------- src/cache/backings/file_common.h | 37 +++++++++++ src/cache/backings/file_mapped.c | 4 +- src/cache/handle.c | 2 +- src/cache/handlers/cdio.c | 23 +++---- src/cache/handlers/http.c | 11 ++-- src/cache/range.h | 2 + src/codec/ffmpeg/decoder.c | 31 ++++----- src/codec/ffmpeg/decoder.h | 4 +- src/codec/ffmpeg/demuxer.c | 2 +- src/fruits/cmc/ui/ext.h | 20 ++++++ src/fruits/cmc/ui/pane_list.c | 3 +- src/fruits/cmc/ui/pane_search.c | 2 + src/fruits/cmc/ui/ui.c | 9 +-- src/fruits/cmsrv/ui.c | 2 +- src/fruits/cmv/cmv.c | 11 ++-- src/fruits/ctv/ctv.c | 2 +- src/liana/list.c | 97 ++++++++++------------------ src/liana/server.c | 2 +- src/libsink/sink.c | 136 +++++++++++++++++++-------------------- src/libsink/sink.h | 9 +-- src/screen/screen.c | 6 +- src/screen/screen.h | 2 +- src/sink/desktop.c | 11 ++-- 30 files changed, 271 insertions(+), 284 deletions(-) delete mode 100644 src/cache/backings/file_common.c create mode 100644 src/cache/backings/file_common.h create mode 100644 src/fruits/cmc/ui/ext.h (limited to 'src') 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 #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.c deleted file mode 100644 index e8bd2ca..0000000 --- a/src/cache/backings/file_common.c +++ /dev/null @@ -1,24 +0,0 @@ -static off_t file_backing_get_size_estimate(struct cch_backing *backing) -{ - struct cch_backing_file *file = (struct cch_backing_file *)backing; - nn_mutex_lock(&file->mutex); - off_t size = file->size; - nn_mutex_unlock(&file->mutex); - return size; -} - -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 (!size) { - file->size = file->file.size; - cch_backing_fill_range(&file->backing, 0, file->size); - } else { - file->size = -1; - if (file->file.size < size) { - nn_file_truncate(&file->file, size); - } - } - return true; -} diff --git a/src/cache/backings/file_common.h b/src/cache/backings/file_common.h new file mode 100644 index 0000000..98bd420 --- /dev/null +++ b/src/cache/backings/file_common.h @@ -0,0 +1,37 @@ +#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; + nn_mutex_lock(&file->mutex); + off_t size = file->size; + nn_mutex_unlock(&file->mutex); + return size; +} + +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 (!size) { + file->size = file->file.size; + cch_backing_fill_range(&file->backing, 0, file->size); + } else { + file->size = -1; + if (file->file.size < size) { + nn_file_truncate(&file->file, size); + } + } + 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 #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 #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 #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 +#define AL_LOG_SECTION "ff_decoder" #include +#include #include #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 +#include + +// 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 #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 #include #include @@ -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 #include +#include #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 -#include -#include #define AL_LOG_SECTION "list" //#define AL_LOG_ENABLE_TRACE #include +#include +#include +#include #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(¤t->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 #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 -- cgit v1.2.3-101-g0448