summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-05-11 15:10:54 -0400
committerAndrew Opalach <andrew@akon.city> 2025-05-11 15:10:54 -0400
commitcb342b234defc1205de5d8b10ddf79deae0a551a (patch)
tree135a8f17ef297dcfa71cfa24de0170797add999e
parentbbdc4ed66aa171f89f675aa1c82316477d5fd47e (diff)
downloadcamu-cb342b234defc1205de5d8b10ddf79deae0a551a.tar.gz
camu-cb342b234defc1205de5d8b10ddf79deae0a551a.tar.bz2
camu-cb342b234defc1205de5d8b10ddf79deae0a551a.zip
Add keybind to disable scaling filter
- Fix no FFmpeg build. - Cleanup commented code from cmc ui. Signed-off-by: Andrew Opalach <andrew@akon.city>
-rw-r--r--docs/references/references.txt4
-rw-r--r--src/codec/codec.h3
-rw-r--r--src/codec/ffmpeg/demuxer.c13
-rw-r--r--src/fruits/cmc/cmc.c8
-rw-r--r--src/fruits/cmc/ui/panes/list.c163
-rw-r--r--src/fruits/cmc/ui/panes/search.h13
-rw-r--r--src/fruits/cmc/ui/ui.c8
-rw-r--r--src/fruits/cmc/ui/ui.h66
-rw-r--r--src/fruits/cmc/ui/util/waveform.c4
-rw-r--r--src/fruits/cmc/ui/widgets/now_playing.c23
-rw-r--r--src/fruits/cmsrv/ui.c2
-rw-r--r--src/fruits/cmv/cmv.c2
-rw-r--r--src/liana/client.c75
-rw-r--r--src/liana/handlers/codec_server.c1
-rw-r--r--src/liana/process.c2
-rw-r--r--src/render/queue_libplacebo.c8
-rw-r--r--src/render/queue_libplacebo.h2
-rw-r--r--src/render/renderer.h6
-rw-r--r--src/render/renderer_libplacebo.c27
-rw-r--r--src/screen/screen.c16
-rw-r--r--src/screen/screen.h1
-rw-r--r--tests/cue_splitter.c10
22 files changed, 178 insertions, 279 deletions
diff --git a/docs/references/references.txt b/docs/references/references.txt
index cf74777..f39942c 100644
--- a/docs/references/references.txt
+++ b/docs/references/references.txt
@@ -36,6 +36,10 @@ Scaling
~~~~~~~
* https://redvice.org/2019/on-anime4k/
+Codecs
+~~~~~~
+* https://stackoverflow.com/questions/70893502/why-does-ffmpeg-output-slightly-different-rgb-values-when-converting-to-gbrp-and
+
Old Video Standards
~~~~~~~~~~~~~~~~~~~
* https://en.wikipedia.org/wiki/24p
diff --git a/src/codec/codec.h b/src/codec/codec.h
index 48f83c7..14727d3 100644
--- a/src/codec/codec.h
+++ b/src/codec/codec.h
@@ -10,7 +10,8 @@
#include "../cache/handle.h"
enum {
- CAMU_LANG_ENGLISH = 0,
+ CAMU_LANG_UNKNOWN = 0,
+ CAMU_LANG_ENGLISH,
CAMU_LANG_JAPANESE
};
diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c
index b539577..bf2039f 100644
--- a/src/codec/ffmpeg/demuxer.c
+++ b/src/codec/ffmpeg/demuxer.c
@@ -5,8 +5,6 @@
#include "demuxer.h"
#include "avio.h"
-#define DEMUX_BUFFER_SIZE 4096
-
static void close_internal(struct camu_ff_demuxer *av)
{
if (av->io_context) {
@@ -30,8 +28,10 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
goto err;
}
- u8 *buf = (u8 *)av_malloc(DEMUX_BUFFER_SIZE);
- av->io_context = avio_alloc_context(buf, DEMUX_BUFFER_SIZE, 0, handle, camu_avio_read, NULL, camu_avio_seek);
+ // This is meant to be the "block size" so, if I understand correctly, that would mean
+ // the smallest amount for 1 read. Therefore, if reading from memory, it would be a page.
+ u8 *buf = (u8 *)av_malloc(al_page_size);
+ av->io_context = avio_alloc_context(buf, al_page_size, 0, handle, camu_avio_read, NULL, camu_avio_seek);
if (!av->io_context) {
log_error("Failed to create custom io context.");
goto err;
@@ -66,8 +66,9 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
av_dict_free(&opts);
- if (avformat_find_stream_info(av->format_context, NULL) < 0) {
- log_error("Failed to find stream info.");
+ ret = avformat_find_stream_info(av->format_context, NULL);
+ if (ret < 0) {
+ log_error("Failed to find stream info (%s).", av_err2str(ret));
goto err;
}
diff --git a/src/fruits/cmc/cmc.c b/src/fruits/cmc/cmc.c
index 39423c1..b9810f6 100644
--- a/src/fruits/cmc/cmc.c
+++ b/src/fruits/cmc/cmc.c
@@ -108,10 +108,10 @@ static void client_callback(void *userdata, u8 op, void *opaque)
al_array_foreach(c->lists, i, list) {
cmc_list_pane_add_list(&c->ui.lists, list);
}
- struct cmc_search *search;
- al_array_foreach(c->searches, i, search) {
- //cmc_sp_add_search(&c->ui, search);
- }
+ //struct cmc_search *search;
+ //al_array_foreach(c->searches, i, search) {
+ // cmc_sp_add_search(&c->ui, search);
+ //}
break;
case CLI_ADD: {
str *arg;
diff --git a/src/fruits/cmc/ui/panes/list.c b/src/fruits/cmc/ui/panes/list.c
index 15554b6..b599cc5 100644
--- a/src/fruits/cmc/ui/panes/list.c
+++ b/src/fruits/cmc/ui/panes/list.c
@@ -291,166 +291,3 @@ void cmc_list_pane_render(struct cmc_list_pane *lp)
render_list_entries(lp, tab, lp->page_length);
cmc_now_playing_render(&lp->np, tab_current_entry(tab));
}
-
-//static void render_now_playing(struct cmc_ui *ui, struct cmc_list_tab *tab, u32 y, u32 height)
-//{
-// struct ncplane *n = ui->lp.n;
-// u32 width = ncplane_dim_x(n);
-//
-// struct cmc_list_entry *entry = NULL;
-// if (tab->list->entries.count > (u32)tab->list->current) {
-// entry = al_array_at(tab->list->entries, tab->list->current);
-// }
-//
-// u64 pos = 0;
-// u64 duration = 0;
-// u64 remaining = 0;
-// u32 y_off = height - 7;
-//
-// ncplane_set_styles(n, NCSTYLE_BOLD);
-// if (entry) {
-// pos = entry->offset;
-// duration = entry->duration;
-// u64 now = nn_get_timestamp();
-// bool paused = entry->start == LIANA_TIMESTAMP_INVALID;
-// if (!paused && now > entry->start) {
-// pos += now - entry->start;
-// }
-// pos = MIN(pos, duration);
-// remaining = duration - pos;
-// //ncplane_putstr_yx(n, y_off, 2, "▸");
-// //ncplane_putstr_yx(n, y_off, 2, "▶");
-// //ncplane_putstr_yx(n, y_off, 2, "⏵ ");
-// //ncplane_putstr_yx(n, y_off, 2, "|");
-// //ncplane_putstr_yx(n, y_off, 2, "|");
-// //ncplane_putstr_yx(n, y_off, 2, "⏵");
-// //ncplane_putstr_yx(n, y_off, 2, "⏸");
-// if (remaining == 0) {
-// ncplane_putstr_yx(n, y_off - 1, 2, "∨");
-// } else {
-// ncplane_putstr_yx(n, y_off - 1, 2, paused ? "^": ">");
-// }
-// } else {
-// ncplane_putstr_yx(n, y_off - 1, 2, "∨");
-// }
-// ncplane_set_styles(n, NCSTYLE_NONE);
-//
-// f32 percent = 1.f;
-// if (duration > 0) percent = MIN(pos / (f32)duration, 1.f);
-// for (u32 i = 0; i < (width - 2) * percent; i++) {
-// ncplane_putchar_yx(n, y_off, i + 1, '-');
-// }
-//
-// y_off--;
-//
-// char timestr[16] = { 0 }; // max = 829128280:01:49\0
-// s32 offset = camu_print_time(timestr, sizeof(timestr), pos, true, 4);
-// ncplane_putstr_yx(n, y_off, 4, timestr);
-// ncplane_putstr_yx(n, y_off, 4 + offset, "⎹");
-//
-// if (entry) {
-// cmc_ui_putnwstr_yx(n, y_off, 6 + offset, MIN(entry->name.length, (u32)60), &entry->name);
-// }
-//
-// bool show_remaining = false;
-// if (show_remaining) {
-// offset = camu_print_time(timestr, sizeof(timestr), remaining, true, 4);
-// } else {
-// offset = camu_print_time(timestr, sizeof(timestr), duration, true, 4);
-// }
-// ncplane_putstr_yx(n, y_off, width - 4 - offset, "⎸");
-// // "=" Duration, "+" Segment, "-" Remaining.
-// if (show_remaining) {
-// ncplane_putstr_yx(n, y_off, width - 3 - offset, "-");
-// } else {
-// ncplane_putstr_yx(n, y_off, width - 3 - offset, "=");
-// }
-// ncplane_putstr_yx(n, y_off, width - 2 - offset, timestr);
-//
-// /*
-// ncplane_putchar_yx(n, height - 5, 2, 'A');
-// ncplane_putchar_yx(n, height - 4, 2, 'A');
-// ncplane_putchar_yx(n, height - 3, 2, 'A');
-// ncplane_putchar_yx(n, height - 2, 2, 'A');
-// */
-//
-// if (entry && entry->raw.data != NULL) {
-// u32 length = width - 2;
-// u32 top = height - 6;
-// u32 wave_height = 5;
-// if (entry->raw.drawing == NULL || entry != ui->lp.blitted) {
-// entry->raw.drawing = al_malloc(sizeof(char **) * wave_height);
-// for (u32 j = 0; j < wave_height; j++) {
-// entry->raw.drawing[j] = al_malloc(sizeof(char *) * length);
-// for (u32 i = 0; i < length; i++) {
-// entry->raw.drawing[j][i] = al_calloc(1, 6);
-// }
-// }
-// if (!ui->lp.w) {
-// struct ncplane_options opts = { 0 };
-// opts.x = 1;
-// opts.y = top;
-// opts.cols = length;
-// opts.rows = wave_height;
-// ui->lp.w = ncplane_create(n, &opts);
-// }
-// /*
-// struct nccell ncl;
-// nccell_init(&ncl);
-// nccell_load(w, &ncl, " ");
-// nccell_set_bg_palindex(&ncl, 3);
-// ncplane_polyfill_yx(w, 0, 0, &ncl);
-// */
-// u32 *rgba;
-// u32 pixel_width, pixel_height;
-// ncplane_pixel_geom(ui->lp.w, &pixel_height, &pixel_width, NULL, NULL, NULL, NULL);
-// //cmc_draw_waveform(entry, length, wave_height, false, entry->raw.drawing, &rgba);
-// cmc_draw_waveform(entry, pixel_width, pixel_height, false, entry->raw.drawing, &rgba);
-// if (ui->lp.vis) {
-// ncvisual_destroy(ui->lp.vis);
-// }
-// ui->lp.vis = ncvisual_from_rgba(rgba, pixel_height, pixel_width * 4, pixel_width);
-// }
-//
-// if (entry != ui->lp.blitted) {
-// ncplane_erase(ui->lp.w);
-// struct ncvisual_options vopts = { 0 };
-// vopts.blitter = NCBLIT_PIXEL;
-// vopts.scaling = NCSCALE_STRETCH;
-// vopts.flags = NCVISUAL_OPTION_NOINTERPOLATE;
-// vopts.n = ui->lp.w;
-// vopts.x = 0;
-// vopts.y = 0;
-// ncvisual_blit(ui->nc, ui->lp.vis, &vopts);
-// ui->lp.blitted = entry;
-// }
-//
-// /*
-// ncplane_set_fg_palindex(n, 5);
-// for (u32 j = 0; j < wave_height; j++) {
-// for (u32 i = 0; i < length; i++) {
-// char *cell = entry->raw.drawing[j][i];
-// if (cell[0] == 'R') {
-// ncplane_set_bg_palindex(n, 2);
-// }
-// ncplane_putstr_yx(n, top + j, 1 + i, cell + 1);
-// if (cell[0] == 'R') {
-// ncplane_set_bg_default(n);
-// }
-// }
-// }
-// ncplane_set_fg_default(n);
-// */
-// }
-//
-// /*
-// char buf[24];
-// al_snprintf(buf, sizeof(buf), "%u, %u | %u, %u", ui->last_mouse_x, ui->last_mouse_y, width, height);
-// ncplane_putstr_yx(n, height - 5, 5, buf);
-// */
-//
-// u64 c = 0;
-// ncchannels_set_fg_default(&c);
-// ncplane_cursor_move_yx(n, y, 0);
-// ncplane_light_box(n, NCSTYLE_NONE, c, height - 1, width - 1, 0);
-//}
diff --git a/src/fruits/cmc/ui/panes/search.h b/src/fruits/cmc/ui/panes/search.h
new file mode 100644
index 0000000..7f9a2a7
--- /dev/null
+++ b/src/fruits/cmc/ui/panes/search.h
@@ -0,0 +1,13 @@
+#pragma once
+
+/*
+struct cmc_search_tab {
+ struct cmc_search *search;
+ struct ncplane *input;
+ u32 cursor;
+ u32 visual_cursor;
+ bool input_active;
+ wstr input_text;
+ bool input_changed;
+};
+*/
diff --git a/src/fruits/cmc/ui/ui.c b/src/fruits/cmc/ui/ui.c
index a5d9125..bc01a22 100644
--- a/src/fruits/cmc/ui/ui.c
+++ b/src/fruits/cmc/ui/ui.c
@@ -81,14 +81,6 @@ void cmc_ui_queue_render(struct cmc_ui *ui)
}
if (ui->overlay_shown) {
- /*
- struct nccell ncl;
- nccell_init(&ncl);
- nccell_load(ui->oln, &ncl, "I");
- //nccell_set_bg_palindex(&ncl, 3);
- nccell_set_fg_palindex(&ncl, 3);
- ncplane_polyfill_yx(ui->oln, 0, 0, &ncl);
- */
u64 c = 0;
ncchannels_set_fg_default(&c);
ncplane_cursor_move_yx(ui->oln, 0, 0);
diff --git a/src/fruits/cmc/ui/ui.h b/src/fruits/cmc/ui/ui.h
index 7abf105..dad2c6b 100644
--- a/src/fruits/cmc/ui/ui.h
+++ b/src/fruits/cmc/ui/ui.h
@@ -16,30 +16,6 @@ enum {
CMC_PANE_LOG
};
-/*
-struct cmc_list_tab {
- struct cmc_list *list;
- s32 page_length;
- s32 selected;
- bool leader_pressed;
- struct {
- bool active;
- s32 selected;
- s32 offset;
- } move;
-};
-
-struct cmc_search_tab {
- struct cmc_search *search;
- struct ncplane *input;
- u32 cursor;
- u32 visual_cursor;
- bool input_active;
- wstr input_text;
- bool input_changed;
-};
-*/
-
struct cmc;
struct cmc_ui {
struct notcurses *nc;
@@ -56,25 +32,6 @@ struct cmc_ui {
u64 last_mouse_ts;
struct cmc_list_pane lists;
struct cmc_log_pane log;
- /*
- struct {
- struct ncplane *n;
- struct ncplane *w;
- struct ncvisual *vis;
- struct cmc_list_entry *blitted;
- array(struct cmc_list_tab) tabs;
- u32 current;
- } lp; // list pane.
- struct {
- struct ncplane *n;
- array(struct cmc_search_tab) tabs;
- u32 current;
- } sp; // search pane.
- struct {
- struct ncplane *n;
- array(char *) messages;
- } logp;
- */
struct nn_poll input_poll;
struct nn_timer render_timer;
struct cmc *c;
@@ -97,26 +54,3 @@ bool cmc_ui_init(struct cmc_ui *ui, struct nn_event_loop *loop, struct cmc *c);
void cmc_ui_queue_render(struct cmc_ui *ui);
void cmc_ui_toggle_overlay(struct cmc_ui *ui);
void cmc_ui_close(struct cmc_ui *ui);
-
-/*
-void cmc_lp_init(struct cmc_ui *ui);
-void cmc_lp_layout(struct cmc_ui *ui, struct ncplane *parent);
-void cmc_lp_add_list(struct cmc_ui *ui, struct cmc_list *list);
-bool cmc_lp_handle_input(struct cmc_ui *ui, struct ncinput *input);
-void cmc_lp_erase(struct cmc_ui *ui);
-void cmc_lp_render(struct cmc_ui *ui);
-
-void cmc_sp_init(struct cmc_ui *ui);
-void cmc_sp_layout(struct cmc_ui *ui, struct ncplane *parent);
-void cmc_sp_add_search(struct cmc_ui *ui, struct cmc_search *search);
-bool cmc_sp_handle_input(struct cmc_ui *ui, struct ncinput *input);
-void cmc_sp_erase(struct cmc_ui *ui);
-void cmc_sp_render(struct cmc_ui *ui);
-
-void cmc_logp_init(struct cmc_ui *ui);
-void cmc_logp_layout(struct cmc_ui *ui, struct ncplane *parent);
-void cmc_logp_push_message(struct cmc_ui *ui, char *message);
-bool cmc_logp_handle_input(struct cmc_ui *ui, struct ncinput *input);
-void cmc_logp_erase(struct cmc_ui *ui);
-void cmc_logp_render(struct cmc_ui *ui);
-*/
diff --git a/src/fruits/cmc/ui/util/waveform.c b/src/fruits/cmc/ui/util/waveform.c
index 8d37543..535f219 100644
--- a/src/fruits/cmc/ui/util/waveform.c
+++ b/src/fruits/cmc/ui/util/waveform.c
@@ -103,6 +103,7 @@ static void test_write_bitmap(struct cmc_list_entry *entry, u32 width, u32 heigh
}
#endif
+/*
static const char *octant_lut[] = {
" ", "𜺨", "𜺫", "🮂", "𜴀", "▘", "𜴁", "𜴂", "𜴃", "𜴄", "▝", "𜴅", "𜴆", "𜴇", "𜴈", "▀",
"𜴉", "𜴊", "𜴋", "𜴌", "🯦", "𜴍", "𜴎", "𜴏", "𜴐", "𜴑", "𜴒", "𜴓", "𜴔", "𜴕", "𜴖", "𜴗",
@@ -121,11 +122,14 @@ static const char *octant_lut[] = {
"𜷋", "𜷌", "𜷍", "𜷎", "𜷏", "𜷐", "𜷑", "𜷒", "𜷓", "𜷔", "𜷕", "𜷖", "𜷗", "𜷘", "𜷙", "𜷚",
"▄", "𜷛", "𜷜", "𜷝", "𜷞", "▙", "𜷟", "𜷠", "𜷡", "𜷢", "▟", "𜷣", "▆", "𜷤", "𜷥", "█"
};
+*/
#define RMS_BIT (1 << 8)
void cmc_draw_waveform(struct cmc_list_entry *entry, u32 width, u32 height, bool include_rms, char ***buf, u32 **rgba)
{
+ (void)include_rms;
+ (void)buf;
#ifdef OUTPUT_WAVEFORM_PNG
test_write_bitmap(entry, width, height, rgba);
return;
diff --git a/src/fruits/cmc/ui/widgets/now_playing.c b/src/fruits/cmc/ui/widgets/now_playing.c
index a90c7e0..748462b 100644
--- a/src/fruits/cmc/ui/widgets/now_playing.c
+++ b/src/fruits/cmc/ui/widgets/now_playing.c
@@ -230,3 +230,26 @@ void cmc_now_playing_render(struct cmc_now_playing *np, struct cmc_list_entry *e
}
ncplane_set_fg_default(np->n);
}
+
+/* Text waveform stuff
+struct nccell ncl;
+nccell_init(&ncl);
+nccell_load(w, &ncl, " ");
+nccell_set_bg_palindex(&ncl, 3);
+ncplane_polyfill_yx(w, 0, 0, &ncl);
+
+ncplane_set_fg_palindex(n, 5);
+for (u32 j = 0; j < wave_height; j++) {
+ for (u32 i = 0; i < length; i++) {
+ char *cell = entry->raw.drawing[j][i];
+ if (cell[0] == 'R') {
+ ncplane_set_bg_palindex(n, 2);
+ }
+ ncplane_putstr_yx(n, top + j, 1 + i, cell + 1);
+ if (cell[0] == 'R') {
+ ncplane_set_bg_default(n);
+ }
+ }
+}
+ncplane_set_fg_default(n);
+*/
diff --git a/src/fruits/cmsrv/ui.c b/src/fruits/cmsrv/ui.c
index c8e9dcb..e5d0798 100644
--- a/src/fruits/cmsrv/ui.c
+++ b/src/fruits/cmsrv/ui.c
@@ -1,8 +1,6 @@
#include <al/lib.h>
#include <al/log.h>
-#include "../../server/common.h"
-
#include "ui.h"
#define LOG_RATIO 1.25
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index c5bb22a..70a0b28 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -96,7 +96,7 @@ static bool parse_exe_name_params(str *exe_name, str *addr, struct lia_prefs *pr
return true;
def:
prefs->enabled_mask = CAMU_MASK_AUDIO | CAMU_MASK_VIDEO | CAMU_MASK_SUBTITLE;
- prefs->audio_lang = CAMU_LANG_ENGLISH;
+ prefs->audio_lang = CAMU_LANG_JAPANESE;
prefs->subtitle_lang = CAMU_LANG_ENGLISH;
return false;
diff --git a/src/liana/client.c b/src/liana/client.c
index d926f9e..164a4d1 100644
--- a/src/liana/client.c
+++ b/src/liana/client.c
@@ -112,33 +112,68 @@ static u8 type_to_mask[] = {
[CAMU_STREAM_SUBTITLE] = CAMU_MASK_SUBTITLE
};
+static const char *type_to_str[] = {
+ [CAMU_STREAM_AUDIO] = "audio",
+ [CAMU_STREAM_VIDEO] = "video",
+ [CAMU_STREAM_SUBTITLE] = "subtitle"
+};
+
static void parse_info_packet(struct lia_client *client, struct nn_packet *packet)
{
str liana;
nn_packet_read_str(packet, &liana);
client->duration = nn_packet_read_u64(packet);
collect_streams(client, packet);
+ struct lia_prefs *prefs = &client->prefs;
u8 selected = 0;
- struct camu_codec_stream *stream;
- al_array_foreach_ptr(client->streams, i, stream) {
- u8 type_mask = type_to_mask[stream->type];
- if ((selected & type_mask) || !(client->prefs.enabled_mask & type_mask)) {
- continue;
- }
- selected |= type_mask;
- client->mask |= 1 << stream->index;
- struct lia_vcr_track *track = al_alloc_object(struct lia_vcr_track);
- track->stream = stream;
- track->client = lia_handler_by_name(&liana)->create_client_handler();
- track->client->callback = client->callback;
- track->client->userdata = client->userdata;
- if (!track->client->init(track->client, client->renderer, track->stream)) {
- track->client->free(&track->client);
- al_free(track);
- continue;
+ u32 accept_defaults = 0;
+ for (; accept_defaults < 2; accept_defaults++) {
+ struct camu_codec_stream *stream;
+ al_array_foreach_ptr(client->streams, i, stream) {
+ u8 type_mask = type_to_mask[stream->type];
+ if ((selected & type_mask) || !(prefs->enabled_mask & type_mask)) continue;
+#ifdef CAMU_HAVE_FFMPEG
+ const AVDictionaryEntry *title = NULL;
+ if (stream->mode == CAMU_FFMPEG_COMPAT) {
+ AVDictionary *metadata = stream->av.stream->metadata;
+ title = av_dict_get(metadata, "title", NULL, 0);
+ const AVDictionaryEntry *lang = av_dict_get(metadata, "language", NULL, 0);
+ if (lang && !accept_defaults) {
+ u8 lang_value = CAMU_LANG_UNKNOWN;
+ if (strcmp(lang->value, "eng") == 0) lang_value = CAMU_LANG_ENGLISH;
+ else if (strcmp(lang->value, "jpn") == 0) lang_value = CAMU_LANG_JAPANESE;
+ switch (stream->type) {
+ case CAMU_STREAM_AUDIO:
+ if (prefs->audio_lang != lang_value) continue;
+ break;
+ case CAMU_STREAM_SUBTITLE:
+ if (prefs->subtitle_lang != lang_value) continue;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ log_info("Selected %s stream (index: %u, title: %s).", type_to_str[stream->type], stream->index, title ? title->value : "(empty)");
+#else
+ log_info("Selected %s stream (index: %u).", type_to_str[stream->type], stream->index);
+#endif
+ selected |= type_mask;
+ client->mask |= 1 << stream->index;
+ struct lia_vcr_track *track = al_alloc_object(struct lia_vcr_track);
+ track->stream = stream;
+ track->client = lia_handler_by_name(&liana)->create_client_handler();
+ track->client->callback = client->callback;
+ track->client->userdata = client->userdata;
+ if (!track->client->init(track->client, client->renderer, track->stream)) {
+ track->client->free(&track->client);
+ al_free(track);
+ // This will NOT attempt to select another stream.
+ continue;
+ }
+ client->callback(client->userdata, LIANA_CLIENT_CONFIGURE, stream, track);
+ lia_vcr_add_track(&client->vcr, track);
}
- client->callback(client->userdata, LIANA_CLIENT_CONFIGURE, stream, track);
- lia_vcr_add_track(&client->vcr, track);
}
client->callback(client->userdata, LIANA_CLIENT_CONFIGURE_COMPLETE, NULL, NULL);
}
@@ -289,12 +324,14 @@ void lia_client_free(struct lia_client *client)
{
lia_vcr_free(&client->vcr);
nn_packet_stream_free(&client->data);
+#ifdef CAMU_HAVE_FFMPEG
struct camu_codec_stream *stream;
al_array_foreach_ptr(client->streams, i, stream) {
if (stream->mode == CAMU_FFMPEG_COMPAT) {
avformat_free_context(stream->av.format_context);
}
}
+#endif
al_array_free(client->streams);
al_str_free(&client->addr);
}
diff --git a/src/liana/handlers/codec_server.c b/src/liana/handlers/codec_server.c
index 042c05b..de2c927 100644
--- a/src/liana/handlers/codec_server.c
+++ b/src/liana/handlers/codec_server.c
@@ -5,7 +5,6 @@
#include "../../codec/ffmpeg/demuxer.h"
#include "../../codec/ffmpeg/packet_ext.h"
#endif
-
#include "../../codec/stb_image/demuxer.h"
#include "../../codec/spng/demuxer.h"
#include "../../codec/wuffs/demuxer.h"
diff --git a/src/liana/process.c b/src/liana/process.c
index c2e4ce4..0a6d6b6 100644
--- a/src/liana/process.c
+++ b/src/liana/process.c
@@ -14,6 +14,7 @@ struct raw_samples_data {
u32 index;
};
+#ifdef CAMU_HAVE_FFMPEG
static u32 append_samples(struct raw_samples_data *raw, u8 *data, u32 sample_count)
{
u32 bytes = sample_count * raw->channels * raw->bps;
@@ -111,3 +112,4 @@ out:
return data->samples != NULL;
}
+#endif
diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c
index 8e17eb7..7fe9258 100644
--- a/src/render/queue_libplacebo.c
+++ b/src/render/queue_libplacebo.c
@@ -340,15 +340,15 @@ static void queue_lp_push_av_frame(struct camu_frame_queue *queue, AVFrame *fram
static void queue_lp_push_subtitle(struct camu_frame_queue *queue, struct camu_codec_packet *packet)
{
struct camu_frame_queue_lp *lq = (struct camu_frame_queue_lp *)queue;
- AVPacket *pkt = packet->av.pkt;
#ifdef CAMU_HAVE_SUBTITLES
+ AVPacket *pkt = packet->av.pkt;
nn_mutex_lock(&lq->subtitle_lock);
al_assert(lq->ass_track && lq->ass_renderer);
ass_process_chunk(lq->ass_track, (const char *)pkt->data, pkt->size, pkt->pts, pkt->duration);
nn_mutex_unlock(&lq->subtitle_lock);
#else
(void)lq;
- (void)pkt;
+ (void)packet;
#endif
}
@@ -400,9 +400,11 @@ static void queue_lp_free(struct camu_frame_queue **queue)
nn_mutex_destroy(&lq->subtitle_lock);
}
#endif
+#ifdef CAMU_HAVE_FFMPEG
if (lq->copy_frame_fallback) {
av_frame_free(&lq->swframe);
}
+#endif
pl_queue_destroy(&lq->queue);
al_free(lq);
*queue = NULL;
@@ -419,8 +421,8 @@ struct camu_frame_queue *camu_frame_queue_lp_create(void)
lq->q.push = queue_lp_push;
#ifdef CAMU_HAVE_FFMPEG
lq->q.push_av_frame = queue_lp_push_av_frame;
- lq->q.push_subtitle = queue_lp_push_subtitle;
#endif
+ lq->q.push_subtitle = queue_lp_push_subtitle;
lq->q.flush = queue_lp_flush;
lq->q.count = queue_lp_count;
lq->q.read = queue_lp_read;
diff --git a/src/render/queue_libplacebo.h b/src/render/queue_libplacebo.h
index eeb562f..2766447 100644
--- a/src/render/queue_libplacebo.h
+++ b/src/render/queue_libplacebo.h
@@ -21,7 +21,9 @@ struct camu_frame_queue_lp {
pl_queue queue;
struct pl_queue_params params;
bool copy_frame_fallback;
+#ifdef CAMU_HAVE_FFMPEG
AVFrame *swframe;
+#endif
array(struct camu_overlay_lp *) overlays;
#ifdef CAMU_HAVE_SUBTITLES
ASS_Library *ass;
diff --git a/src/render/renderer.h b/src/render/renderer.h
index b4863a0..1e6ffc0 100644
--- a/src/render/renderer.h
+++ b/src/render/renderer.h
@@ -19,6 +19,11 @@
#include "../codec/codec.h"
+enum {
+ CAMU_SCALING_DEFAULT = 0,
+ CAMU_SCALING_NEAREST
+};
+
struct camu_frame_queue;
struct camu_screen;
struct camu_renderer {
@@ -48,6 +53,7 @@ struct camu_renderer {
u32 (*get_latency)(struct camu_renderer *);
void (*resize)(struct camu_renderer *, u32 *, u32 *);
void (*set_fullscreen)(struct camu_renderer *, bool);
+ void (*set_scaling)(struct camu_renderer *, u8);
void (*render)(struct camu_renderer *, struct camu_screen *, bool);
#ifdef CAMU_HAVE_FFMPEG
s32 (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, s32 flags);
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index 8f816b4..a2105d6 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -52,6 +52,23 @@ static void renderer_lp_set_fullscreen(struct camu_renderer *renderer, bool full
}
#endif
+static void renderer_lp_set_scaling(struct camu_renderer *renderer, u8 mode)
+{
+ struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer;
+ switch (mode) {
+ case CAMU_SCALING_DEFAULT:
+ lr->params.upscaler = pl_render_default_params.upscaler;
+ lr->params.downscaler = pl_render_default_params.downscaler;
+ lr->params.skip_anti_aliasing = pl_render_default_params.skip_anti_aliasing;
+ break;
+ case CAMU_SCALING_NEAREST:
+ lr->params.upscaler = &pl_filter_nearest;
+ lr->params.downscaler = &pl_filter_nearest;
+ lr->params.skip_anti_aliasing = true;
+ break;
+ }
+}
+
static void log_callback(void *userdata, enum pl_log_level level, const char *message)
{
(void)userdata;
@@ -88,6 +105,12 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid
clear_color[1] = ((global_color_palette.colors[0] >> 8) & 0xff) / 255.f;
clear_color[2] = ((global_color_palette.colors[0]) & 0xff) / 255.f;
+ /*
+ clear_color[0] = 255.f;
+ clear_color[1] = 255.f;
+ clear_color[2] = 255.f;
+ */
+
lr->logger = pl_log_create(PL_API_VER, pl_log_params(
.log_cb = log_callback,
.log_priv = NULL,
@@ -201,10 +224,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid
lr->have_frame = false;
al_memset(&lr->params, 0, sizeof(struct pl_render_params));
- //lr->params = pl_render_fast_params;
- //lr->params.upscaler = &pl_filter_nearest;
lr->params = pl_render_default_params;
- //lr->params = pl_render_high_quality_params;
lr->params.deband_params = NULL;
//lr->params.frame_mixer = NULL;
@@ -418,6 +438,7 @@ struct camu_renderer *camu_renderer_lp_create(void)
#else
lr->r.set_fullscreen = NULL;
#endif
+ lr->r.set_scaling = renderer_lp_set_scaling;
lr->r.render = renderer_lp_render;
lr->r.free = renderer_lp_free;
return (struct camu_renderer *)lr;
diff --git a/src/screen/screen.c b/src/screen/screen.c
index f749bcb..23afa7e 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -1,3 +1,5 @@
+#define AL_LOG_SECTION "screen"
+#include <al/log.h>
#include <nnwt/thread.h>
#include <math.h>
@@ -297,6 +299,16 @@ static bool key_callback(void *userdata, u8 state, u16 button)
}
break;
}
+ case STELA_KEY_N:
+ scr->scaling_disabled = !scr->scaling_disabled;
+ if (scr->scaling_disabled) {
+ scr->renderer->set_scaling(scr->renderer, CAMU_SCALING_NEAREST);
+ log_info("Scaling filters disabled.");
+ } else {
+ scr->renderer->set_scaling(scr->renderer, CAMU_SCALING_DEFAULT);
+ log_info("Scaling filters enabled.");
+ }
+ return true;
default:
break;
}
@@ -324,7 +336,7 @@ static void key_immediate_callback(void *userdata, u8 state, u16 button)
switch (state) {
case STELA_BUTTON_PRESSED:
switch (button) {
- case STELA_KEY_F: {
+ case STELA_KEY_F:
scr->fullscreen = !scr->fullscreen;
if (scr->renderer->set_fullscreen) {
scr->renderer->set_fullscreen(scr->renderer, scr->fullscreen);
@@ -333,7 +345,6 @@ static void key_immediate_callback(void *userdata, u8 state, u16 button)
}
break;
}
- }
break;
default:
break;
@@ -390,6 +401,7 @@ bool camu_screen_create_window(struct camu_screen *scr, const char *name)
scr->width = scr->window->width;
scr->height = scr->window->height;
scr->fullscreen = false;
+ scr->scaling_disabled = false;
#ifdef STELA_EVENT_BUFFER
nn_thread_create(&scr->thread, event_thread, scr);
#endif
diff --git a/src/screen/screen.h b/src/screen/screen.h
index bf1f519..4ba07c2 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -63,6 +63,7 @@ struct camu_screen {
u32 width;
u32 height;
bool fullscreen;
+ bool scaling_disabled;
u64 last_click_ts;
f64 last_mouse_y;
f64 last_mouse_x;
diff --git a/tests/cue_splitter.c b/tests/cue_splitter.c
index f34ec83..833d3ac 100644
--- a/tests/cue_splitter.c
+++ b/tests/cue_splitter.c
@@ -4,6 +4,7 @@
#include <nnwt/file.h>
#include <libcue.h>
+#ifdef CAMU_HAVE_FFMPEG
#include "../src/codec/codec.h"
#include "../src/codec/ffmpeg/demuxer.h"
#include "../src/codec/ffmpeg/decoder.h"
@@ -23,6 +24,7 @@ struct worker_info {
static void data_callback(void *userdata, struct camu_codec_frame *frame)
{
struct worker_info *info = (struct worker_info *)userdata;
+ (void)info;
(void)frame;
}
@@ -118,6 +120,8 @@ s32 main(s32 argc, char *argv[])
return EXIT_FAILURE;
}
+ (void)worker_thread;
+
str input_path = al_str_cr(argv[1]);
struct nn_file input;
if (!nn_file_open(&input, &input_path, NNWT_FILE_READONLY)) {
@@ -190,3 +194,9 @@ s32 main(s32 argc, char *argv[])
return EXIT_SUCCESS;
}
+#else
+s32 main(void)
+{
+ return EXIT_FAILURE;
+}
+#endif