add Line2x pillarbox option

This commit is contained in:
marqs 2025-10-30 00:21:36 +02:00
parent 32af38e252
commit 8c0a0c181d
9 changed files with 52 additions and 22 deletions

View File

@ -153,7 +153,7 @@ set_interface_property osd_if CMSIS_SVD_VARIABLES ""
set_interface_property osd_if SVD_ADDRESS_GROUP ""
add_interface_port osd_if vclk vclk Input 1
add_interface_port osd_if xpos xpos Input 11
add_interface_port osd_if xpos xpos Input 12
add_interface_port osd_if ypos ypos Input 11
add_interface_port osd_if osd_enable osd_enable Output 1
add_interface_port osd_if osd_color osd_color Output 3

View File

@ -32,7 +32,7 @@ module osd_generator_top (
output avalon_s_waitrequest_n,
// OSD interface
input vclk,
input [10:0] xpos,
input [11:0] xpos,
input [10:0] ypos,
output reg osd_enable,
output reg [2:0] osd_color
@ -56,7 +56,7 @@ localparam OSD_ROW_COLOR_REGNUM = 8'hf3;
reg [31:0] osd_config;
reg [31:0] config_reg[OSD_ROW_LSEC_ENABLE_REGNUM:OSD_ROW_COLOR_REGNUM] /* synthesis ramstyle = "logic" */;
reg [10:0] xpos_osd_area_scaled, xpos_text_scaled;
reg [11:0] xpos_osd_area_scaled, xpos_text_scaled;
reg [10:0] ypos_osd_area_scaled, ypos_text_scaled;
reg [7:0] x_ptr[2:5], y_ptr[2:5] /* synthesis ramstyle = "logic" */;
reg osd_text_act_lsec_x_hit, osd_text_act_lsec_en, osd_text_act_rsec_x_hit, osd_text_act_rsec_en, osd_text_act_y_hit;
@ -76,7 +76,7 @@ wire [1:0] y_size = osd_config[14:13];
wire [2:0] border_color = osd_config[17:15];
wire [2:0] highlight_color = osd_config[20:18];
wire [10:0] xpos_scaled_w = (xpos >> x_size)-({3'h0, x_offset} << 3);
wire [11:0] xpos_scaled_w = (xpos >> x_size)-({3'h0, x_offset} << 3);
wire [10:0] ypos_scaled_w = (ypos >> y_size)-({3'h0, y_offset} << 3);
wire [7:0] rom_rdaddr;
wire [0:7] char_data[7:0];

View File

@ -140,7 +140,7 @@ wire lcd_bl_timeout;
wire [2:0] osd_color;
wire osd_enable_pre;
wire osd_enable = osd_enable_pre & ~lt_active;
wire [10:0] xpos_sc;
wire [11:0] xpos_sc;
wire [10:0] ypos_sc;
wire [3:0] x_ctr_shmask, y_ctr_shmask;
wire [10:0] shmask_data;

View File

@ -930,7 +930,9 @@ void print_vm_stats() {
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "Profile:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%u: %s", profile_sel, (target_profile_name[0] == 0) ? "<empty>" : target_profile_name);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "FW:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%u.%.2u" FW_SUFFIX " @ " __DATE__, FW_VER_MAJOR, FW_VER_MINOR);
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, "%u.%.2u" FW_SUFFIX, FW_VER_MAJOR, FW_VER_MINOR);
sniprintf((char*)osd->osd_array.data[++row][0], OSD_CHAR_COLS, "FW date:");
sniprintf((char*)osd->osd_array.data[row][1], OSD_CHAR_COLS, __DATE__);
osd->osd_config.status_refresh = 1;
osd->osd_row_color.mask = 0;

View File

@ -106,6 +106,7 @@ typedef struct {
alt_u8 adc_pll_bw;
alt_u8 fpga_pll_bw;
alt_u8 panasonic_hack;
alt_u8 o480p_pbox;
/* Postprocessing settings */
alt_u8 sl_mode;

View File

@ -28,14 +28,14 @@
#define DEF_PHASE 0x10
#define H_TOTAL_MIN 300
#define H_TOTAL_MAX 2800
#define H_TOTAL_MAX 3200
#define H_TOTAL_ADJ_MAX 19
#define H_SYNCLEN_MIN 10
#define H_SYNCLEN_MAX 255
#define H_BPORCH_MIN 0
#define H_BPORCH_MAX 511
#define H_ACTIVE_MIN 200
#define H_ACTIVE_MAX 2560
#define H_ACTIVE_MAX 3000
#define H_ACTIVE_SMP_MAX 2048
#define V_SYNCLEN_MIN 1
#define V_SYNCLEN_MAX 15

View File

@ -156,7 +156,7 @@ MENU(menu_cust_sl, P99_PROTECT({ \
}))
MENU(menu_vinputproc, P99_PROTECT({ \
MENU(menu_vinput_opt, P99_PROTECT({ \
{ LNG("Video LPF","ビデオ LPF"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.video_lpf, OPT_WRAP, SETTING_ITEM(video_lpf_desc) } } },
{ LNG("Reverse LPF","ギャクLPF"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.reverse_lpf, OPT_NOWRAP, 0, REVERSE_LPF_MAX, value_disp } } },
{ LNG("YPbPr in ColSpa","イロクウカンニYPbPr"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.ypbpr_cs, OPT_WRAP, SETTING_ITEM(ypbpr_cs_desc) } } },
@ -175,13 +175,6 @@ MENU(menu_vinputproc, P99_PROTECT({ \
{ "<Custom Lc-set>", OPT_CUSTOMMENU, { .cstm = { &cstm_lc_palette_set_load } } },
}))
MENU(menu_sampling, P99_PROTECT({ \
{ LNG("480p in sampler","サンプラーデ480p"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.s480p_mode, OPT_WRAP, SETTING_ITEM(s480p_mode_desc) } } },
{ LNG("400p in sampler","サンプラーデ400p"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.s400p_mode, OPT_WRAP, SETTING_ITEM(s400p_mode_desc) } } },
{ LNG("Allow upsample2x","アップサンプル2xキョヨウ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.upsample2x, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("<Adv. timing >","<カクシュタイミング>"), OPT_SUBMENU, { .sub = { &menu_advtiming, &vm_arg_info, vm_select } } },
}))
MENU(menu_sync, P99_PROTECT({ \
{ LNG("Analog sync LPF","アナログドウキ LPF"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sync_lpf, OPT_WRAP, SETTING_ITEM(sync_lpf_desc) } } },
{ "Analog STC LPF", OPT_AVCONFIG_SELECTION, { .sel = { &tc.stc_lpf, OPT_WRAP, SETTING_ITEM(stc_lpf_desc) } } },
@ -194,7 +187,7 @@ MENU(menu_sync, P99_PROTECT({ \
{ "FPGA PLL BW", OPT_AVCONFIG_SELECTION, { .sel = { &tc.fpga_pll_bw, OPT_WRAP, SETTING_ITEM(fpga_pll_bw_desc) } } },
}))
MENU(menu_output, P99_PROTECT({ \
MENU(menu_lm, P99_PROTECT({ \
{ LNG("240p/288p proc","240p/288pショリ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.pm_240p, OPT_WRAP, SETTING_ITEM(pm_240p_desc) } } },
{ LNG("384p/400p proc","384p/400pショリ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.pm_384p, OPT_WRAP, SETTING_ITEM(pm_384p_desc) } } },
{ LNG("480i/576i proc","480i/576iショリ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.pm_480i, OPT_WRAP, SETTING_ITEM(pm_480i_desc) } } },
@ -208,10 +201,18 @@ MENU(menu_output, P99_PROTECT({ \
{ LNG("Line6x mode","Line6xモード"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.l6_mode, OPT_WRAP, SETTING_ITEM(l2l4l5l6_mode_desc) } } },
{ LNG("Line5x format","Line5xケイシキ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.l5_fmt, OPT_WRAP, SETTING_ITEM(l5_fmt_desc) } } },
{ LNG("256x240 aspect","256x240アスペクト"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.ar_256col, OPT_WRAP, SETTING_ITEM(ar_256col_desc) } } },
{ LNG("480p in sampler","サンプラーデ480p"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.s480p_mode, OPT_WRAP, SETTING_ITEM(s480p_mode_desc) } } },
{ LNG("400p in sampler","サンプラーデ400p"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.s400p_mode, OPT_WRAP, SETTING_ITEM(s400p_mode_desc) } } },
{ LNG("Allow upsample2x","アップサンプル2xキョヨウ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.upsample2x, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("<Adv. timing >","<カクシュタイミング>"), OPT_SUBMENU, { .sub = { &menu_advtiming, &vm_arg_info, vm_select } } },
}))
MENU(menu_output, P99_PROTECT({ \
{ LNG("TX mode","TXモード"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.tx_mode, OPT_WRAP, SETTING_ITEM(tx_mode_desc) } } },
{ "HDMI ITC", OPT_AVCONFIG_SELECTION, { .sel = { &tc.hdmi_itc, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "HDMI HDR flag", OPT_AVCONFIG_SELECTION, { .sel = { &tc.hdmi_hdr, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "HDMI VRR flag", OPT_AVCONFIG_SELECTION, { .sel = { &tc.hdmi_vrr, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "480p/576p pbox", OPT_AVCONFIG_SELECTION, { .sel = { &tc.o480p_pbox, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
}))
MENU(menu_scanlines, P99_PROTECT({ \
@ -277,9 +278,9 @@ MENU(menu_settings, P99_PROTECT({ \
MENU(menu_main, P99_PROTECT({ \
{ LNG("Video in proc >","タイオウエイゾウ >"), OPT_SUBMENU, { .sub = { &menu_vinputproc, NULL, NULL } } },
{ LNG("Sampling opt. >","サンプリングオプション>"), OPT_SUBMENU, { .sub = { &menu_sampling, NULL, NULL } } },
{ LNG("Video in opt. >","タイオウエイゾウ >"), OPT_SUBMENU, { .sub = { &menu_vinput_opt, NULL, NULL } } },
{ LNG("Sync opt. >","ドウキオプション >"), OPT_SUBMENU, { .sub = { &menu_sync, NULL, NULL } } },
{ "Line mult opt. >", OPT_SUBMENU, { .sub = { &menu_lm, NULL, NULL } } },
{ LNG("Output opt. >","シュツリョクオプション >"), OPT_SUBMENU, { .sub = { &menu_output, NULL, NULL } } },
{ LNG("Scanline opt. >","スキャンラインオプション >"), OPT_SUBMENU, { .sub = { &menu_scanlines, NULL, NULL } } },
{ LNG("Post-proc. >","アトショリ >"), OPT_SUBMENU, { .sub = { &menu_postproc, NULL, NULL } } },

View File

@ -139,6 +139,7 @@ const ude_item_map ude_profile_items[] = {
UDE_ITEM(64, 120, tc.link_av),
// 65 reserved
UDE_ITEM(66, 120, tc.panasonic_hack),
UDE_ITEM(67, 120, tc.o480p_pbox),
};
int write_userdata(uint8_t entry) {

View File

@ -133,7 +133,7 @@ uint32_t calculate_pclk(uint32_t src_clk_hz, mode_data_t *vm_out, vm_proc_config
int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf)
{
int i, diff_lines, diff_v_hz_x100, mindiff_id=0, mindiff_lines=1000, mindiff_v_hz_x100=10000;
int i, diff_lines, diff_v_hz_x100, mindiff_id=0, mindiff_lines=1000, mindiff_v_hz_x100=10000, x_rpt_decr=0;
mode_data_t *mode_preset;
mode_flags valid_lm[] = { (MODE_PT | (cc->pt_mode ? (MODE_L5_GEN_4_3<<(cc->pt_mode-1)) : 0)),
(MODE_L2 | (MODE_L2<<cc->l2_mode)),
@ -267,7 +267,10 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm
case MODE_PT:
vm_out->vic = vm_in->vic;
if ((cc->pt_mode == 1) && ((mode_preset->group >= GROUP_384P) && (mode_preset->group <= GROUP_576P))) {
if ((cc->pt_mode == 0) && (cc->o480p_pbox) && ((mode_preset->group >= GROUP_480P) && (mode_preset->group <= GROUP_576P))) {
vm_conf->x_rpt = vm_conf->h_skip = 3;
x_rpt_decr += 1;
} else if ((cc->pt_mode == 1) && ((mode_preset->group >= GROUP_384P) && (mode_preset->group <= GROUP_576P))) {
vmode_hv_mult(vm_in, 2, 1);
vmode_hv_mult(vm_out, 2, 1);
} else if ((cc->pt_mode >= 2) && (mode_preset->group >= GROUP_240P) && (mode_preset->group <= GROUP_288P)) {
@ -291,6 +294,10 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
} else {
if (cc->o480p_pbox) {
vm_conf->x_rpt = vm_conf->h_skip = 3;
x_rpt_decr += 1;
}
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
}
break;
@ -338,6 +345,14 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm
case MODE_L2_512_COL:
case MODE_L2_384_COL:
case MODE_L2_320_COL:
if (cc->o480p_pbox) {
vm_conf->x_rpt = vm_conf->h_skip = 3;
x_rpt_decr += 1;
} else {
vm_conf->x_rpt = vm_conf->h_skip = 1;
}
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
break;
case MODE_L3_512_COL:
case MODE_L4_512_COL:
case MODE_L6_512_COL:
@ -345,6 +360,14 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
break;
case MODE_L2_256_COL:
if (cc->o480p_pbox) {
vm_conf->x_rpt = vm_conf->h_skip = 7;
x_rpt_decr += 2;
} else {
vm_conf->x_rpt = vm_conf->h_skip = 2;
}
vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT);
break;
case MODE_L3_384_COL:
case MODE_L4_384_COL:
case MODE_L5_512_COL:
@ -391,7 +414,9 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm
vm_conf->x_rpt = cc->ar_256col ? 2 : 3;
if (mindiff_lm & (MODE_L3_320_COL|MODE_L2_240x360|MODE_L3_240x360))
vm_conf->x_rpt--;
x_rpt_decr += 1;
vm_conf->x_rpt -= x_rpt_decr;
if (mindiff_lm == MODE_L2_240x360) {
vm_out->timings.h_active += 80;