kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Pi Firmware: implemented capture of N frames and OSD_EXPIRED for delayed exit of OSD
Change-Id: I93a75ae4f6fb34fc778250431d65c63fd7593579pull/11/head
rodzic
8212858fa6
commit
bb06d34cc7
|
@ -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_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_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 MASK_LAST_BUFFER (3 << OFFSET_LAST_BUFFER)
|
||||
|
@ -63,6 +63,7 @@
|
|||
#define RET_SW1 0x02
|
||||
#define RET_SW2 0x04
|
||||
#define RET_SW3 0x08
|
||||
#define RET_EXPIRED 0x10
|
||||
|
||||
// Channel definitions
|
||||
#define NUM_CHANNELS 3
|
||||
|
@ -125,6 +126,7 @@
|
|||
#define O_NLINES 20
|
||||
#define O_H_OFFSET 24
|
||||
#define O_V_OFFSET 28
|
||||
#define O_NCAPTURE 32
|
||||
|
||||
#else
|
||||
|
||||
|
@ -137,6 +139,7 @@ typedef struct {
|
|||
int nlines; // number of active lines to capture each field
|
||||
int h_offset; // horizontal offset (in psync clocks)
|
||||
int v_offset; // vertical offset (in lines)
|
||||
int ncapture; // number of fields to capture, or -1 to capture forever
|
||||
} capture_info_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
17
src/osd.c
17
src/osd.c
|
@ -388,10 +388,6 @@ static void update_palette() {
|
|||
RPI_PropertyProcess();
|
||||
}
|
||||
|
||||
static void delay() {
|
||||
for (volatile int i = 0; i < 100000000; i++);
|
||||
}
|
||||
|
||||
static int get_feature(int num) {
|
||||
switch (num) {
|
||||
case F_PALETTE:
|
||||
|
@ -793,12 +789,13 @@ void osd_refresh() {
|
|||
}
|
||||
}
|
||||
|
||||
void osd_key(int key) {
|
||||
int osd_key(int key) {
|
||||
item_type_t type;
|
||||
base_menu_item_t *item = current_menu[depth]->items[current_item[depth]];
|
||||
child_menu_item_t *child_item = (child_menu_item_t *)item;
|
||||
param_menu_item_t *param_item = (param_menu_item_t *)item;
|
||||
int val;
|
||||
int ret = -1;
|
||||
|
||||
switch (osd_state) {
|
||||
|
||||
|
@ -813,14 +810,15 @@ void osd_key(int key) {
|
|||
// Clock Calibration
|
||||
osd_set(0, ATTR_DOUBLE_SIZE, "Clock Calibration");
|
||||
action_calibrate_clocks();
|
||||
// Note: due to multiple buffering, the message sometimes doesn't get displayed
|
||||
delay();
|
||||
osd_clear();
|
||||
// Fire OSD_EXPIRED in 50 frames time
|
||||
ret = 50;
|
||||
} else if (key == key_auto_cal) {
|
||||
// Auto Calibration
|
||||
osd_set(0, ATTR_DOUBLE_SIZE, "Auto Calibration");
|
||||
action_calibrate_auto();
|
||||
delay();
|
||||
// Fire OSD_EXPIRED in 50 frames time
|
||||
ret = 50;
|
||||
} else if (key == OSD_EXPIRED) {
|
||||
osd_clear();
|
||||
}
|
||||
break;
|
||||
|
@ -928,6 +926,7 @@ void osd_key(int key) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void osd_init() {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#ifndef OSD_H
|
||||
#define OSD_H
|
||||
|
||||
#define OSD_SW1 1
|
||||
#define OSD_SW2 2
|
||||
#define OSD_SW3 3
|
||||
#define OSD_SW1 1
|
||||
#define OSD_SW2 2
|
||||
#define OSD_SW3 3
|
||||
#define OSD_EXPIRED 4
|
||||
|
||||
#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_fast(uint32_t *osd_base, int bytes_per_line);
|
||||
int osd_active();
|
||||
void osd_key(int key);
|
||||
int osd_key(int key);
|
||||
uint32_t *osd_get_palette();
|
||||
|
||||
void action_calibrate_clocks();
|
||||
|
|
|
@ -678,6 +678,8 @@ rgb_to_fb:
|
|||
str r2, param_h_offset
|
||||
ldr r2, [r0, #O_V_OFFSET]
|
||||
str r2, param_v_offset
|
||||
ldr r2, [r0, #O_NCAPTURE]
|
||||
str r2, param_ncapture
|
||||
ldr r2, [r0, #O_FB_BASE]
|
||||
str r2, param_framebuffer0
|
||||
|
||||
|
@ -963,6 +965,9 @@ param_h_offset:
|
|||
param_v_offset:
|
||||
.word 0
|
||||
|
||||
param_ncapture:
|
||||
.word 0
|
||||
|
||||
// Insert the current literal pool, otherwise constants are to far away and you get a build error
|
||||
.ltorg
|
||||
|
||||
|
@ -994,14 +999,19 @@ skip_osd_update:
|
|||
FLIP_BUFFER
|
||||
#endif
|
||||
|
||||
// Loop back if not calibrate mode...
|
||||
tst r3, #BIT_CALIBRATE
|
||||
beq frame
|
||||
// Loop back if required number of fields has not been reached
|
||||
// or if negative (capture forever)
|
||||
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
|
||||
tst r3, #BIT_CAL_COUNT
|
||||
orr r3, #BIT_CAL_COUNT
|
||||
beq frame
|
||||
// Setup the response code
|
||||
mov r0, r3
|
||||
and r0, #BIT_MODE7
|
||||
orr r0, #RET_EXPIRED
|
||||
|
||||
// Return
|
||||
exit:
|
||||
|
|
|
@ -520,7 +520,10 @@ static int test_for_elk(capture_info_t *capinfo, int elk, int mode7) {
|
|||
}
|
||||
|
||||
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
|
||||
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;
|
||||
#endif
|
||||
|
||||
// In mode 0..6, set BIT_CAL_COUNT to 1 (capture 1 field)
|
||||
// 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);
|
||||
unsigned int flags = mode7 | BIT_CALIBRATE | ((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
|
||||
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);
|
||||
|
||||
// Capture two fields
|
||||
capinfo->ncapture = 2;
|
||||
|
||||
// Grab a frame
|
||||
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;
|
||||
#endif
|
||||
|
||||
// In mode 0..6, set BIT_CAL_COUNT to 1 (capture 1 field)
|
||||
// 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);
|
||||
unsigned int flags = mode7 | BIT_CALIBRATE | ((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++) {
|
||||
int total = 0;
|
||||
|
@ -1039,6 +1049,7 @@ void rgb_to_hdmi_main() {
|
|||
int fb_size_changed;
|
||||
int active_size_decreased;
|
||||
int clk_changed;
|
||||
int ncapture;
|
||||
|
||||
capture_info_t last_capinfo;
|
||||
clk_info_t last_clkinfo;
|
||||
|
@ -1051,6 +1062,9 @@ void rgb_to_hdmi_main() {
|
|||
// Determine initial mode
|
||||
mode7 = rgb_to_fb(capinfo, BIT_PROBE) & BIT_MODE7 & !m7disable;
|
||||
|
||||
// Default to capturing indefinitely
|
||||
ncapture = -1;
|
||||
|
||||
while (1) {
|
||||
|
||||
// Switch the the approriate capinfo structure instance
|
||||
|
@ -1073,7 +1087,6 @@ void rgb_to_hdmi_main() {
|
|||
|
||||
do {
|
||||
|
||||
log_debug("Entering rgb_to_fb");
|
||||
int flags = mode7 | clear;
|
||||
if (!m7disable) {
|
||||
flags |= BIT_MODE_DETECT;
|
||||
|
@ -1104,18 +1117,20 @@ void rgb_to_hdmi_main() {
|
|||
#ifdef MULTI_BUFFER
|
||||
flags |= nbuffers << OFFSET_NBUFFERS;
|
||||
#endif
|
||||
capinfo->ncapture = ncapture;
|
||||
log_debug("Entering rgb_to_fb, flags=%08x", flags);
|
||||
result = rgb_to_fb(capinfo, flags);
|
||||
log_debug("Leaving rgb_to_fb, result=%04x", result);
|
||||
clear = 0;
|
||||
|
||||
if (result & RET_SW1) {
|
||||
osd_key(OSD_SW1);
|
||||
}
|
||||
if (result & RET_SW2) {
|
||||
osd_key(OSD_SW2);
|
||||
}
|
||||
if (result & RET_SW3) {
|
||||
osd_key(OSD_SW3);
|
||||
if (result & RET_EXPIRED) {
|
||||
ncapture = osd_key(OSD_EXPIRED);
|
||||
} else if (result & RET_SW1) {
|
||||
ncapture = osd_key(OSD_SW1);
|
||||
} else if (result & RET_SW2) {
|
||||
ncapture = osd_key(OSD_SW2);
|
||||
} else if (result & RET_SW3) {
|
||||
ncapture = osd_key(OSD_SW3);
|
||||
}
|
||||
|
||||
// Possibly the size or offset has been adjusted, so update current capinfo
|
||||
|
|
Ładowanie…
Reference in New Issue