First attempt at vertical genlock

pull/12/head
IanSB 2018-11-29 04:49:12 +00:00
rodzic f8c3da4360
commit ff36d8fd5a
5 zmienionych plików z 93 dodań i 8 usunięć

Wyświetl plik

@ -104,7 +104,8 @@ enum {
F_NBUFFERS,
#endif
F_M7DISABLE,
F_DEBUG
F_DEBUG,
F_VLOCK
};
static param_t features[] = {
@ -120,6 +121,7 @@ static param_t features[] = {
#endif
{ F_M7DISABLE, "Mode7 Disable", 0, 1, 1 },
{ F_DEBUG, "Debug", 0, 1, 1 },
{ F_VLOCK, "Vertical Lock", 1, 100, 1 },
{ -1, NULL, 0, 0, 0 },
};
@ -203,6 +205,7 @@ static param_menu_item_t nbuffers_ref = { I_FEATURE, &features[F_NBUFFERS]
#endif
static param_menu_item_t m7disable_ref = { I_FEATURE, &features[F_M7DISABLE] };
static param_menu_item_t debug_ref = { I_FEATURE, &features[F_DEBUG] };
static param_menu_item_t vlock_ref = { I_FEATURE, &features[F_VLOCK] };
static menu_t processing_menu = {
"Processing Menu",
@ -215,7 +218,6 @@ static menu_t processing_menu = {
}
};
static menu_t settings_menu = {
"Settings Menu",
{
@ -227,6 +229,7 @@ static menu_t settings_menu = {
(base_menu_item_t *) &vsync_ref,
(base_menu_item_t *) &pllh_ref,
(base_menu_item_t *) &nbuffers_ref,
(base_menu_item_t *) &vlock_ref,
NULL
}
};
@ -416,6 +419,8 @@ static int get_feature(int num) {
return get_debug();
case F_M7DISABLE:
return get_m7disable();
case F_VLOCK:
return get_vlockline();
}
return -1;
}
@ -457,6 +462,9 @@ static void set_feature(int num, int value) {
case F_M7DISABLE:
set_m7disable(value);
break;
case F_VLOCK:
set_vlockline(value);
break;
}
}

Wyświetl plik

@ -82,6 +82,8 @@ void set_vsync(int on);
int get_vsync();
void set_pllh(int val);
int get_pllh();
void set_vlockline(int val);
int get_vlockline();
#ifdef MULTI_BUFFER
void set_nbuffers(int val);
int get_nbuffers();

Wyświetl plik

@ -11,6 +11,8 @@
.global sw1counter
.global sw2counter
.global sw3counter
.global vsync_line
// ======================================================================
// Macros
@ -59,6 +61,7 @@
CLEAR_VSYNC
// Mark the next line in red
orr r3, r3, #BIT_VSYNC_MARKER
str r5, vsync_line
novsync\@:
.endm
@ -456,6 +459,10 @@ skip_osd_update:
FLIP_BUFFER
#endif
push {r0-r12, lr}
bl recalculate_hdmi_clock_line_locked_update
pop {r0-r12, lr}
// Loop back if required number of fields has not been reached
// or if negative (capture forever)
ldr r5, param_ncapture
@ -674,3 +681,9 @@ param_capture_line:
linecountmod10:
.word 0
vsync_line:
.word 0

Wyświetl plik

@ -25,4 +25,8 @@ extern int capture_line_default_8bpp();
extern int capture_line_mode7_4bpp();
extern int vsync_line;
void recalculate_hdmi_clock_line_locked_update();
#endif

Wyświetl plik

@ -67,6 +67,7 @@ static int clear;
static volatile int delay;
static double pllh_clock = 0;
// =============================================================
// OSD parameters
// =============================================================
@ -79,10 +80,13 @@ static int scanlines = 0;
static int deinterlace = 0;
static int vsync = 0;
static int pllh = 0;
static int vlockline = 40;
#ifdef MULTI_BUFFER
static int nbuffers = 0;
#endif
static int current_pllh = 0xffffffff;
// Calculated so that the constants from librpitx work
static volatile uint32_t *gpioreg = (volatile uint32_t *)(PERIPHERAL_BASE + 0x101000UL);
@ -359,7 +363,9 @@ static int calibrate_sampling_clock() {
return a;
}
static void recalculate_hdmi_clock() {
static void recalculate_hdmi_clock(int pllh) { // use local pllh, not global
// The very first time we get called, vsync_time_ns has not been set
// so exit gracefully
@ -468,6 +474,50 @@ static void recalculate_hdmi_clock() {
gpioreg[PLLH_STS]);
}
static void recalculate_hdmi_clock_once(int pllh) {
if (current_pllh != pllh){
current_pllh = pllh;
recalculate_hdmi_clock(pllh);
}
}
void recalculate_hdmi_clock_line_locked_update() {
if (pllh != HDMI_EXACT) {
recalculate_hdmi_clock_once(pllh);
}
else {
signed int difference = 0;
if (vsync_line > (capinfo->height/4))
difference = vsync_line - vlockline - capinfo->height/2;
else
difference = vsync_line - vlockline;
if (abs(difference) > 1) {
if (difference >=0) {
if (difference < 20)
recalculate_hdmi_clock_once(HDMI_SLOW_1000PPM);
else
recalculate_hdmi_clock_once(HDMI_SLOW_2000PPM);
}
else {
if (difference > -20)
recalculate_hdmi_clock_once(HDMI_FAST_1000PPM);
else
recalculate_hdmi_clock_once(HDMI_FAST_2000PPM);
}
}
else
recalculate_hdmi_clock_once(HDMI_EXACT);
}
}
static void init_hardware() {
int i;
for (i = 0; i < 12; i++) {
@ -1012,7 +1062,15 @@ int get_m7disable() {
return m7disable;
}
void set_vsync(int on) {
void set_vlockline(int val) {
vlockline = val;
}
int get_vlockline() {
return vlockline;
}
void set_vsync(int on) {
vsync = on;
}
@ -1026,7 +1084,7 @@ int get_pllh() {
void set_pllh(int val) {
pllh = val;
recalculate_hdmi_clock();
recalculate_hdmi_clock_line_locked_update();
}
void set_scanlines(int on) {
@ -1136,8 +1194,8 @@ void rgb_to_hdmi_main() {
calibrate_sampling_clock();
// Recalculate the HDMI clock (if the pllh property requires this)
recalculate_hdmi_clock();
recalculate_hdmi_clock_line_locked_update();
clear = BIT_CLEAR;
osd_refresh();
@ -1172,7 +1230,7 @@ void rgb_to_hdmi_main() {
result = rgb_to_fb(capinfo, flags);
log_debug("Leaving rgb_to_fb, result=%04x", result);
clear = 0;
if (result & RET_EXPIRED) {
ncapture = osd_key(OSD_EXPIRED);
} else if (result & RET_SW1) {