Pi Firmware: implemented capture of N frames and OSD_EXPIRED for delayed exit of OSD

Change-Id: I93a75ae4f6fb34fc778250431d65c63fd7593579
pull/11/head
David Banks 2018-11-18 14:54:29 +00:00
rodzic 8212858fa6
commit bb06d34cc7
5 zmienionych plików z 65 dodań i 37 usunięć

Wyświetl plik

@ -34,7 +34,7 @@
#define BIT_FIELD_TYPE 0x100 // bit 8, indicates the field type (0 = odd, 1 = even) of the last field #define BIT_FIELD_TYPE 0x100 // bit 8, indicates the field type (0 = odd, 1 = even) of the last field
#define BIT_CLEAR 0x200 // bit 9, indicates the frame buffer should be cleared #define BIT_CLEAR 0x200 // bit 9, indicates the frame buffer should be cleared
#define BIT_VSYNC 0x400 // bit 10, indicates the vsync frequency is being probed #define BIT_VSYNC 0x400 // bit 10, indicates the vsync frequency is being probed
#define BIT_CAL_COUNT 0x800 // bit 11, indicates how many fields to capture during calibration (1 or 2) // bit 11, unused
#define OFFSET_LAST_BUFFER 12 // bit 12-13 LAST_BUFFER #define OFFSET_LAST_BUFFER 12 // bit 12-13 LAST_BUFFER
#define MASK_LAST_BUFFER (3 << OFFSET_LAST_BUFFER) #define MASK_LAST_BUFFER (3 << OFFSET_LAST_BUFFER)
@ -63,6 +63,7 @@
#define RET_SW1 0x02 #define RET_SW1 0x02
#define RET_SW2 0x04 #define RET_SW2 0x04
#define RET_SW3 0x08 #define RET_SW3 0x08
#define RET_EXPIRED 0x10
// Channel definitions // Channel definitions
#define NUM_CHANNELS 3 #define NUM_CHANNELS 3
@ -125,6 +126,7 @@
#define O_NLINES 20 #define O_NLINES 20
#define O_H_OFFSET 24 #define O_H_OFFSET 24
#define O_V_OFFSET 28 #define O_V_OFFSET 28
#define O_NCAPTURE 32
#else #else
@ -137,6 +139,7 @@ typedef struct {
int nlines; // number of active lines to capture each field int nlines; // number of active lines to capture each field
int h_offset; // horizontal offset (in psync clocks) int h_offset; // horizontal offset (in psync clocks)
int v_offset; // vertical offset (in lines) int v_offset; // vertical offset (in lines)
int ncapture; // number of fields to capture, or -1 to capture forever
} capture_info_t; } capture_info_t;
typedef struct { typedef struct {

Wyświetl plik

@ -388,10 +388,6 @@ static void update_palette() {
RPI_PropertyProcess(); RPI_PropertyProcess();
} }
static void delay() {
for (volatile int i = 0; i < 100000000; i++);
}
static int get_feature(int num) { static int get_feature(int num) {
switch (num) { switch (num) {
case F_PALETTE: case F_PALETTE:
@ -793,12 +789,13 @@ void osd_refresh() {
} }
} }
void osd_key(int key) { int osd_key(int key) {
item_type_t type; item_type_t type;
base_menu_item_t *item = current_menu[depth]->items[current_item[depth]]; base_menu_item_t *item = current_menu[depth]->items[current_item[depth]];
child_menu_item_t *child_item = (child_menu_item_t *)item; child_menu_item_t *child_item = (child_menu_item_t *)item;
param_menu_item_t *param_item = (param_menu_item_t *)item; param_menu_item_t *param_item = (param_menu_item_t *)item;
int val; int val;
int ret = -1;
switch (osd_state) { switch (osd_state) {
@ -813,14 +810,15 @@ void osd_key(int key) {
// Clock Calibration // Clock Calibration
osd_set(0, ATTR_DOUBLE_SIZE, "Clock Calibration"); osd_set(0, ATTR_DOUBLE_SIZE, "Clock Calibration");
action_calibrate_clocks(); action_calibrate_clocks();
// Note: due to multiple buffering, the message sometimes doesn't get displayed // Fire OSD_EXPIRED in 50 frames time
delay(); ret = 50;
osd_clear();
} else if (key == key_auto_cal) { } else if (key == key_auto_cal) {
// Auto Calibration // Auto Calibration
osd_set(0, ATTR_DOUBLE_SIZE, "Auto Calibration"); osd_set(0, ATTR_DOUBLE_SIZE, "Auto Calibration");
action_calibrate_auto(); action_calibrate_auto();
delay(); // Fire OSD_EXPIRED in 50 frames time
ret = 50;
} else if (key == OSD_EXPIRED) {
osd_clear(); osd_clear();
} }
break; break;
@ -928,6 +926,7 @@ void osd_key(int key) {
} }
break; break;
} }
return ret;
} }
void osd_init() { void osd_init() {

Wyświetl plik

@ -4,6 +4,7 @@
#define OSD_SW1 1 #define OSD_SW1 1
#define OSD_SW2 2 #define OSD_SW2 2
#define OSD_SW3 3 #define OSD_SW3 3
#define OSD_EXPIRED 4
#define ATTR_DOUBLE_SIZE (1 << 0) #define ATTR_DOUBLE_SIZE (1 << 0)
@ -53,7 +54,7 @@ void osd_refresh();
void osd_update(uint32_t *osd_base, int bytes_per_line); void osd_update(uint32_t *osd_base, int bytes_per_line);
void osd_update_fast(uint32_t *osd_base, int bytes_per_line); void osd_update_fast(uint32_t *osd_base, int bytes_per_line);
int osd_active(); int osd_active();
void osd_key(int key); int osd_key(int key);
uint32_t *osd_get_palette(); uint32_t *osd_get_palette();
void action_calibrate_clocks(); void action_calibrate_clocks();

Wyświetl plik

@ -678,6 +678,8 @@ rgb_to_fb:
str r2, param_h_offset str r2, param_h_offset
ldr r2, [r0, #O_V_OFFSET] ldr r2, [r0, #O_V_OFFSET]
str r2, param_v_offset str r2, param_v_offset
ldr r2, [r0, #O_NCAPTURE]
str r2, param_ncapture
ldr r2, [r0, #O_FB_BASE] ldr r2, [r0, #O_FB_BASE]
str r2, param_framebuffer0 str r2, param_framebuffer0
@ -963,6 +965,9 @@ param_h_offset:
param_v_offset: param_v_offset:
.word 0 .word 0
param_ncapture:
.word 0
// Insert the current literal pool, otherwise constants are to far away and you get a build error // Insert the current literal pool, otherwise constants are to far away and you get a build error
.ltorg .ltorg
@ -994,14 +999,19 @@ skip_osd_update:
FLIP_BUFFER FLIP_BUFFER
#endif #endif
// Loop back if not calibrate mode... // Loop back if required number of fields has not been reached
tst r3, #BIT_CALIBRATE // or if negative (capture forever)
beq frame ldr r5, param_ncapture
cmp r5, #0
blt frame
sub r5, #1
str r5, param_ncapture
bne frame
// In calibrate mode, have the required number of fields (1 or 2) been captured // Setup the response code
tst r3, #BIT_CAL_COUNT mov r0, r3
orr r3, #BIT_CAL_COUNT and r0, #BIT_MODE7
beq frame orr r0, #RET_EXPIRED
// Return // Return
exit: exit:

Wyświetl plik

@ -520,7 +520,10 @@ static int test_for_elk(capture_info_t *capinfo, int elk, int mode7) {
} }
unsigned int ret; unsigned int ret;
unsigned int flags = BIT_CALIBRATE | BIT_CAL_COUNT | (2 << OFFSET_NBUFFERS); unsigned int flags = BIT_CALIBRATE | (2 << OFFSET_NBUFFERS);
// Set to capture exactly one field
capinfo->ncapture = 1;
// Grab one field // Grab one field
ret = rgb_to_fb(capinfo, flags); ret = rgb_to_fb(capinfo, flags);
@ -615,9 +618,11 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
unsigned int t_compare = 0; unsigned int t_compare = 0;
#endif #endif
// In mode 0..6, set BIT_CAL_COUNT to 1 (capture 1 field) unsigned int flags = mode7 | BIT_CALIBRATE | ((elk & !mode7) ? BIT_ELK : 0) | (2 << OFFSET_NBUFFERS);
// In mode 7, set BIT_CAL_COUNT to 0 (capture two fields, doesn't matter whether odd-even or even-odd)
unsigned int flags = mode7 | BIT_CALIBRATE | (mode7 ? 0 : BIT_CAL_COUNT) | ((elk & !mode7) ? BIT_ELK : 0) | (2 << OFFSET_NBUFFERS); // In mode 0..6, capture one field
// In mode 7, capture two fields
capinfo->ncapture = mode7 ? 2 : 1;
#ifdef INSTRUMENT_CAL #ifdef INSTRUMENT_CAL
t = _get_cycle_counter(); t = _get_cycle_counter();
@ -783,6 +788,9 @@ int analyze_mode7_alignment(capture_info_t *capinfo) {
unsigned int flags = BIT_MODE7 | BIT_CALIBRATE | (2 << OFFSET_NBUFFERS); unsigned int flags = BIT_MODE7 | BIT_CALIBRATE | (2 << OFFSET_NBUFFERS);
// Capture two fields
capinfo->ncapture = 2;
// Grab a frame // Grab a frame
int ret = rgb_to_fb(capinfo, flags); int ret = rgb_to_fb(capinfo, flags);
@ -858,9 +866,11 @@ int total_N_frames(capture_info_t *capinfo, int n, int mode7, int elk) {
unsigned int t_compare = 0; unsigned int t_compare = 0;
#endif #endif
// In mode 0..6, set BIT_CAL_COUNT to 1 (capture 1 field) unsigned int flags = mode7 | BIT_CALIBRATE | ((elk & !mode7) ? BIT_ELK : 0) | (2 << OFFSET_NBUFFERS);
// In mode 7, set BIT_CAL_COUNT to 0 (capture two fields, doesn't matter whether odd-even or even-odd)
unsigned int flags = mode7 | BIT_CALIBRATE | (mode7 ? 0 : BIT_CAL_COUNT) | ((elk & !mode7) ? BIT_ELK : 0) | (2 << OFFSET_NBUFFERS); // In mode 0..6, capture one field
// In mode 7, capture two fields
capinfo->ncapture = mode7 ? 2 : 1;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
int total = 0; int total = 0;
@ -1039,6 +1049,7 @@ void rgb_to_hdmi_main() {
int fb_size_changed; int fb_size_changed;
int active_size_decreased; int active_size_decreased;
int clk_changed; int clk_changed;
int ncapture;
capture_info_t last_capinfo; capture_info_t last_capinfo;
clk_info_t last_clkinfo; clk_info_t last_clkinfo;
@ -1051,6 +1062,9 @@ void rgb_to_hdmi_main() {
// Determine initial mode // Determine initial mode
mode7 = rgb_to_fb(capinfo, BIT_PROBE) & BIT_MODE7 & !m7disable; mode7 = rgb_to_fb(capinfo, BIT_PROBE) & BIT_MODE7 & !m7disable;
// Default to capturing indefinitely
ncapture = -1;
while (1) { while (1) {
// Switch the the approriate capinfo structure instance // Switch the the approriate capinfo structure instance
@ -1073,7 +1087,6 @@ void rgb_to_hdmi_main() {
do { do {
log_debug("Entering rgb_to_fb");
int flags = mode7 | clear; int flags = mode7 | clear;
if (!m7disable) { if (!m7disable) {
flags |= BIT_MODE_DETECT; flags |= BIT_MODE_DETECT;
@ -1104,18 +1117,20 @@ void rgb_to_hdmi_main() {
#ifdef MULTI_BUFFER #ifdef MULTI_BUFFER
flags |= nbuffers << OFFSET_NBUFFERS; flags |= nbuffers << OFFSET_NBUFFERS;
#endif #endif
capinfo->ncapture = ncapture;
log_debug("Entering rgb_to_fb, flags=%08x", flags);
result = rgb_to_fb(capinfo, flags); result = rgb_to_fb(capinfo, flags);
log_debug("Leaving rgb_to_fb, result=%04x", result); log_debug("Leaving rgb_to_fb, result=%04x", result);
clear = 0; clear = 0;
if (result & RET_SW1) { if (result & RET_EXPIRED) {
osd_key(OSD_SW1); ncapture = osd_key(OSD_EXPIRED);
} } else if (result & RET_SW1) {
if (result & RET_SW2) { ncapture = osd_key(OSD_SW1);
osd_key(OSD_SW2); } else if (result & RET_SW2) {
} ncapture = osd_key(OSD_SW2);
if (result & RET_SW3) { } else if (result & RET_SW3) {
osd_key(OSD_SW3); ncapture = osd_key(OSD_SW3);
} }
// Possibly the size or offset has been adjusted, so update current capinfo // Possibly the size or offset has been adjusted, so update current capinfo