Add "Sync glitch filt" compatibility option

While an input is locked, single-shot deviations of the frontend
measurements (line count, field period beyond PCNT_TOLERANCE, hsync width
beyond HSYNC_WIDTH_TOLERANCE, activity flag or the validity check) make
get_status() re-program the mode or drop sync. A NeXT SoG source produced
such glitches (868 -> 814 -> 868 lines) every few minutes, each one a
visible blink.

With this option on, a deviation is acted upon only once it has been seen
on three consecutive status reads; the first two deviating reads are
replaced by the previous stable values. That is 30 ms in the normal case
and up to about 105 ms if the vsync wait in get_status() times out on every
read. Counting deviating reads (rather than requiring identical readings)
guarantees that a real mode change or sync loss is always accepted on the
third read. The counter is cleared whenever the input is not locked or the
option is off. Default Off (stock behaviour). Stored as profile item id 69.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WiXHy7Jhh5yTdsBaenucgw
This commit is contained in:
Peter YooandClaude Fable 5.1 committed 2026-09-18 22:10:53 +09:00
1 parent 5ff096e9d4
commit 88577e1467
4 files changed
+33 -1

No files matched your search

+30 -1
View File
@@ -70,6 +70,7 @@ tvp_input_t target_tvp;
tvp_sync_input_t target_tvp_sync;
alt_u8 target_type;
alt_u8 update_cur_vm;
static alt_u8 glitch_dev_ctr; // "Sync glitch filt": consecutive deviating status reads while locked
// Default settings
const settings_t ts_default = {
@@ -369,9 +370,37 @@ status_t get_status(tvp_sync_input_t syncinput)
pcnt_field = (unsigned long)sc->fe_status2.pcnt_field;
hsync_width = (unsigned long)sc->fe_status2.hsync_width;
clkcnt = (totlines>>!progressive) ? pcnt_field/(totlines>>!progressive) : 0;
valid_mode = (pcnt_field > 0) && check_linecnt(progressive, totlines);
// Optional glitch filter: while locked, act on a changed measurement (line count, field period, hsync width,
// activity flag or validity) only once it has deviated on 3 consecutive status reads (30 ms, up to ~105 ms if
// the vsync wait above times out on every read); until then keep the previous values. Single-shot glitches
// (e.g. 868 -> 814 -> 868 lines seen on a NeXT SoG source) otherwise trigger a mode re-program or a
// sync-loss/re-lock cycle. Counting reads rather than requiring identical candidate values guarantees that a
// real change or loss is always accepted on the third read.
if (!tc.sync_glitch_filt || !cm.sync_active) {
glitch_dev_ctr = 0;
} else {
alt_u8 deviates = !sync_active || !valid_mode ||
(totlines != cm.totlines) || (progressive != cm.progressive) ||
(pcnt_field < (cm.pcnt_field - PCNT_TOLERANCE)) || (pcnt_field > (cm.pcnt_field + PCNT_TOLERANCE)) ||
(abs(((int)hsync_width - (int)cm.hsync_width)) > HSYNC_WIDTH_TOLERANCE);
if (!deviates) {
glitch_dev_ctr = 0;
} else if (glitch_dev_ctr < 2) {
glitch_dev_ctr++;
sync_active = 1;
valid_mode = 1;
totlines = cm.totlines;
progressive = cm.progressive;
pcnt_field = cm.pcnt_field;
hsync_width = cm.hsync_width;
}
}
clkcnt = (totlines>>!progressive) ? pcnt_field/(totlines>>!progressive) : 0;
// Check sync activity
if (!cm.sync_active && sync_active && valid_mode) {
cm.sync_active = 1;
+1
View File
@@ -160,6 +160,7 @@ typedef struct {
alt_u8 av3_alt_rgb;
avinput_t link_av;
alt_u8 pc_sog_coast;
alt_u8 sync_glitch_filt;
} __attribute__((packed)) avconfig_t;
int set_default_profile(int update_cc);
+1
View File
@@ -249,6 +249,7 @@ MENU(menu_compatibility, P99_PROTECT({ \
{ "Panasonic hack", OPT_AVCONFIG_SELECTION, { .sel = { &tc.panasonic_hack, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "Disable PR2x", OPT_AVCONFIG_SELECTION, { .sel = { &tc.hdmi_pr2x_disable, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "PC SoG/CS coast", OPT_AVCONFIG_SELECTION, { .sel = { &tc.pc_sog_coast, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "Sync glitch filt", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sync_glitch_filt, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
}))
MENU(menu_audio, P99_PROTECT({ \
+1
View File
@@ -145,6 +145,7 @@ const ude_item_map ude_profile_items[] = {
UDE_ITEM(61, 122, tc.hdmi_ar),
UDE_ITEM(61, 122, tc.hdmi_pr2x_disable),
UDE_ITEM(68, 122, tc.pc_sog_coast),
UDE_ITEM(69, 122, tc.sync_glitch_filt),
};
int write_userdata(uint8_t entry) {