From 1d201a300bdd5761ae7b05b36d8226e949891364 Mon Sep 17 00:00:00 2001 From: zakk4223 Date: Mon, 31 Mar 2025 02:30:30 -0400 Subject: [PATCH] Add interlaced video vertical filter (#976) --- cfg.cpp | 1 + cfg.h | 1 + menu.cpp | 61 +++++++++++++++++++++++++++++++------------------------ video.cpp | 19 ++++++++++++++--- video.h | 15 ++++++++------ 5 files changed, 62 insertions(+), 35 deletions(-) diff --git a/cfg.cpp b/cfg.cpp index 129e16d..811118b 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -131,6 +131,7 @@ static const ini_var_t ini_vars[] = { "OSD_LOCK_TIME", (void*)(&(cfg.osd_lock_time)), UINT16, 0, 60 }, { "DEBUG", (void *)(&(cfg.debug)), UINT8, 0, 1 }, { "MAIN", (void*)(&(cfg.main)), STRING, 0, sizeof(cfg.main) - 1 }, + {"VFILTER_INTERLACE_DEFAULT", (void*)(&(cfg.vfilter_interlace_default)), STRING, 0, sizeof(cfg.vfilter_interlace_default) - 1 }, }; static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t)); diff --git a/cfg.h b/cfg.h index 491ba29..1789a68 100644 --- a/cfg.h +++ b/cfg.h @@ -99,6 +99,7 @@ typedef struct { uint16_t osd_lock_time; char debug; char main[1024]; + char vfilter_interlace_default[1023]; } cfg_t; extern cfg_t cfg; diff --git a/menu.cpp b/menu.cpp index a096b22..7947f0c 100644 --- a/menu.cpp +++ b/menu.cpp @@ -2820,7 +2820,7 @@ void HandleUI(void) case MENU_VIDEOPROC1: helptext_idx = 0; - menumask = 0x1FFF; + menumask = 0x7FFF; OsdSetTitle("Video Processing"); menustate = MENU_VIDEOPROC2; parentstate = MENU_VIDEOPROC1; @@ -2843,6 +2843,7 @@ void HandleUI(void) strcat(s, " \x16 "); MenuWrite(n++, s, menusub == 2, !video_get_scaler_flt(VFILTER_HORZ) || !S_ISDIR(getFileType(COEFF_DIR))); + MenuWrite(n++); sprintf(s, " Vert filter: %s", video_get_scaler_flt(VFILTER_VERT) ? "From file" : "Same as Horz"); MenuWrite(n++, s, menusub == 3, cfg.direct_video || !video_get_scaler_flt(VFILTER_HORZ)); @@ -2863,31 +2864,42 @@ void HandleUI(void) strcat(s, " \x16 "); MenuWrite(n++, s, menusub == 6, !video_get_scaler_flt(VFILTER_SCAN) || !video_get_scaler_flt(VFILTER_HORZ) || !S_ISDIR(getFileType(COEFF_DIR)) || cfg.direct_video); + MenuWrite(n++); + sprintf(s, " Intl filter: %s", video_get_scaler_flt(VFILTER_ILACE) ? "From file" : "Same as Horz"); + MenuWrite(n++, s, menusub == 7, cfg.direct_video || !video_get_scaler_flt(VFILTER_HORZ)); + strcpy(s, " "); + if (strlen(video_get_scaler_coeff(VFILTER_ILACE))) strncat(s, video_get_scaler_coeff(VFILTER_ILACE), 25); + else strcpy(s, " < none >"); + while (strlen(s) < 26) strcat(s, " "); + strcat(s, " \x16 "); + MenuWrite(n++, s, menusub == 8, !video_get_scaler_flt(VFILTER_ILACE) || !video_get_scaler_flt(VFILTER_HORZ) || !S_ISDIR(getFileType(COEFF_DIR)) || cfg.direct_video); + + MenuWrite(n++); sprintf(s, " Gamma correction - %s", (video_get_gamma_en() > 0) ? "On" : "Off"); - MenuWrite(n++, s, menusub == 7, video_get_gamma_en() < 0); + MenuWrite(n++, s, menusub == 9, video_get_gamma_en() < 0); strcpy(s, " "); if (strlen(video_get_gamma_curve())) strncat(s, video_get_gamma_curve(), 25); else strcpy(s, " < none >"); while (strlen(s) < 26) strcat(s, " "); strcat(s, " \x16 "); - MenuWrite(n++, s, menusub == 8, (video_get_gamma_en() <= 0) || !S_ISDIR(getFileType(GAMMA_DIR))); + MenuWrite(n++, s, menusub == 10, (video_get_gamma_en() <= 0) || !S_ISDIR(getFileType(GAMMA_DIR))); MenuWrite(n++); sprintf(s, " Shadow Mask - %s", (video_get_shadow_mask_mode() < 0) ? config_smask_msg[0] : config_smask_msg[video_get_shadow_mask_mode()]); - MenuWrite(n++, s, menusub == 9, video_get_shadow_mask_mode() < 0); + MenuWrite(n++, s, menusub == 11, video_get_shadow_mask_mode() < 0); strcpy(s, " "); if (strlen(video_get_shadow_mask())) strncat(s, video_get_shadow_mask(), 25); else strcpy(s, " < none >"); while (strlen(s) < 26) strcat(s, " "); strcat(s, " \x16 "); - MenuWrite(n++, s, menusub == 10, (video_get_shadow_mask_mode() <= 0) || !S_ISDIR(getFileType(SMASK_DIR))); + MenuWrite(n++, s, menusub == 12, (video_get_shadow_mask_mode() <= 0) || !S_ISDIR(getFileType(SMASK_DIR))); MenuWrite(n++); - MenuWrite(n++, " Reset to Defaults", menusub == 11); + MenuWrite(n++, " Reset to Defaults", menusub == 13); MenuWrite(n++); - MenuWrite(n++, STD_BACK, menusub == 12); + MenuWrite(n++, STD_BACK, menusub == 14); if (!adjvisible) break; firstmenu += adjvisible; @@ -2897,7 +2909,7 @@ void HandleUI(void) case MENU_VIDEOPROC2: if (menu || left) { - menusub = 6; + menusub = 8; menustate = MENU_COMMON1; break; } @@ -2926,7 +2938,8 @@ void HandleUI(void) case 2: case 4: case 6: - vfilter_type = (menusub == 2) ? VFILTER_HORZ : (menusub == 4) ? VFILTER_VERT : VFILTER_SCAN; + case 8: + vfilter_type = (menusub == 2) ? VFILTER_HORZ : (menusub == 4) ? VFILTER_VERT : (menusub == 6) ? VFILTER_SCAN : VFILTER_ILACE; if(video_get_scaler_flt(VFILTER_HORZ) && video_get_scaler_flt(vfilter_type)) { const char *newfile = flist_GetPrevNext(COEFF_DIR, video_get_scaler_coeff(vfilter_type, 0), "TXT", plus); @@ -2934,7 +2947,7 @@ void HandleUI(void) } break; - case 8: + case 10: if(video_get_gamma_en() > 0) { const char *newfile = flist_GetPrevNext(GAMMA_DIR, video_get_gamma_curve(0), "TXT", plus); @@ -2942,7 +2955,7 @@ void HandleUI(void) } break; - case 10: + case 12: if (video_get_shadow_mask_mode() > 0) { const char *newfile = flist_GetPrevNext(SMASK_DIR, video_get_shadow_mask(0), "TXT", plus); @@ -2970,7 +2983,8 @@ void HandleUI(void) case 2: case 4: case 6: - vfilter_type = (menusub == 2) ? VFILTER_HORZ : (menusub == 4) ? VFILTER_VERT : VFILTER_SCAN; + case 8: + vfilter_type = (menusub == 2) ? VFILTER_HORZ : (menusub == 4) ? VFILTER_VERT : (menusub == 6) ? VFILTER_SCAN : VFILTER_ILACE; if (video_get_scaler_flt(VFILTER_HORZ)) { snprintf(Selected_tmp, sizeof(Selected_tmp), COEFF_DIR"/%s", video_get_scaler_coeff(vfilter_type, 0)); @@ -2980,27 +2994,22 @@ void HandleUI(void) break; case 3: - if (!cfg.direct_video && video_get_scaler_flt(VFILTER_HORZ)) - { - video_set_scaler_flt(VFILTER_VERT, video_get_scaler_flt(VFILTER_VERT) ? 0 : 1); - menustate = parentstate; - } - break; - case 5: + case 7: if (!cfg.direct_video && video_get_scaler_flt(VFILTER_HORZ)) { - video_set_scaler_flt(VFILTER_SCAN, video_get_scaler_flt(VFILTER_SCAN) ? 0 : 1); + vfilter_type = (menusub == 3) ? VFILTER_VERT : (menusub == 5) ? VFILTER_SCAN : VFILTER_ILACE; + video_set_scaler_flt(vfilter_type, video_get_scaler_flt(vfilter_type) ? 0 : 1); menustate = parentstate; } break; - case 7: + case 9: if (video_get_gamma_en() >= 0) video_set_gamma_en(video_get_gamma_en() ? 0 : 1); menustate = parentstate; break; - case 8: + case 10: if (video_get_gamma_en() > 0) { snprintf(Selected_tmp, sizeof(Selected_tmp), GAMMA_DIR"/%s", video_get_gamma_curve(0)); @@ -3009,12 +3018,12 @@ void HandleUI(void) } break; - case 9: + case 11: if (video_get_shadow_mask_mode() >= 0) video_set_shadow_mask_mode(video_get_shadow_mask_mode() + 1); menustate = parentstate; break; - case 10: + case 12: if (video_get_shadow_mask_mode() > 0) { snprintf(Selected_tmp, sizeof(Selected_tmp), SMASK_DIR"/%s", video_get_shadow_mask(0)); @@ -3023,12 +3032,12 @@ void HandleUI(void) } break; - case 11: + case 13: video_cfg_reset(); menustate = parentstate; break; - case 12: + case 14: menusub = 6; menustate = MENU_COMMON1; break; diff --git a/video.cpp b/video.cpp index 3effee5..0878034 100644 --- a/video.cpp +++ b/video.cpp @@ -305,7 +305,7 @@ struct ScalerFilter char filename[1023]; }; -static ScalerFilter scaler_flt[3]; +static ScalerFilter scaler_flt[4]; struct FilterPhase { @@ -331,7 +331,7 @@ struct VideoFilter VideoFilterDigest digest; }; -static VideoFilter scaler_flt_data[3]; +static VideoFilter scaler_flt_data[4]; static bool scale_phases(FilterPhase out_phases[N_PHASES], FilterPhase *in_phases, int in_count) { @@ -534,6 +534,7 @@ static void set_vfilter(int force) { PROFILE_FUNCTION(); + static int last_flags = 0; int flt_flags = spi_uio_cmd_cont(UIO_SET_FLTNUM); @@ -550,7 +551,7 @@ static void set_vfilter(int force) DisableIO(); int vert_flt; - if (current_video_info.interlaced) vert_flt = VFILTER_HORZ; + if (current_video_info.interlaced) vert_flt = scaler_flt[VFILTER_ILACE].mode ? VFILTER_ILACE : VFILTER_HORZ; else if ((flt_flags & 0x30) && scaler_flt[VFILTER_SCAN].mode) vert_flt = VFILTER_SCAN; else if (scaler_flt[VFILTER_VERT].mode) vert_flt = VFILTER_VERT; else vert_flt = VFILTER_HORZ; @@ -661,11 +662,18 @@ static void loadScalerCfg() strcpy(scaler_flt[VFILTER_SCAN].filename, cfg.vfilter_scanlines_default); scaler_flt[VFILTER_SCAN].mode = 1; } + + if (cfg.vfilter_interlace_default[0]) + { + strcpy(scaler_flt[VFILTER_ILACE].filename, cfg.vfilter_interlace_default); + scaler_flt[VFILTER_ILACE].mode = 1; + } } if (!read_video_filter(VFILTER_HORZ, &scaler_flt_data[VFILTER_HORZ])) memset(&scaler_flt[VFILTER_HORZ], 0, sizeof(scaler_flt[VFILTER_HORZ])); if (!read_video_filter(VFILTER_VERT, &scaler_flt_data[VFILTER_VERT])) memset(&scaler_flt[VFILTER_VERT], 0, sizeof(scaler_flt[VFILTER_VERT])); if (!read_video_filter(VFILTER_SCAN, &scaler_flt_data[VFILTER_SCAN])) memset(&scaler_flt[VFILTER_SCAN], 0, sizeof(scaler_flt[VFILTER_SCAN])); + if (!read_video_filter(VFILTER_ILACE, &scaler_flt_data[VFILTER_ILACE])) memset(&scaler_flt[VFILTER_ILACE], 0, sizeof(scaler_flt[VFILTER_ILACE])); } static char active_gamma_cfg[1024] = { 0 }; @@ -1047,6 +1055,11 @@ void video_loadPreset(char *name, bool save) load_flt_pres(line + 8, VFILTER_SCAN); scaler_dirty = true; } + else if (!strncasecmp(line, "ifilter=", 8)) + { + load_flt_pres(line + 8, VFILTER_ILACE); + scaler_dirty = true; + } else if (!strncasecmp(line, "mask=", 5)) { mask_dirty = true; diff --git a/video.h b/video.h index 30ecab9..e8e7cb7 100644 --- a/video.h +++ b/video.h @@ -1,13 +1,14 @@ #ifndef VIDEO_H #define VIDEO_H -#define VFILTER_HORZ 0 -#define VFILTER_VERT 1 -#define VFILTER_SCAN 2 +#define VFILTER_HORZ 0 +#define VFILTER_VERT 1 +#define VFILTER_SCAN 2 +#define VFILTER_ILACE 3 struct VideoInfo { - uint32_t width; + uint32_t width; uint32_t height; uint32_t htime; uint32_t vtime; @@ -25,8 +26,8 @@ struct VideoInfo uint32_t de_h; uint32_t de_v; - bool interlaced; - bool rotated; + bool interlaced; + bool rotated; }; void video_init(); @@ -36,6 +37,8 @@ void video_set_scaler_flt(int type, int n); char* video_get_scaler_coeff(int type, int only_name = 1); void video_set_scaler_coeff(int type, const char *name); + + int video_get_gamma_en(); void video_set_gamma_en(int n); char* video_get_gamma_curve(int only_name = 1);