Pi Firmware: support both old (non-aligned) and new (aligned) deintelacing, fall back gracefully on CPLDv1

Change-Id: I253666a0fedf4cb84dbc2885d148da9328c12ed2
pull/11/head
David Banks 2018-11-10 15:41:59 +00:00
rodzic f3a7b47bff
commit 369313fbeb
6 zmienionych plików z 84 dodań i 47 usunięć

Wyświetl plik

@ -10,8 +10,8 @@
typedef struct {
const char *name;
const int min;
const int max;
int min;
int max;
} param_t;
// Define a common interface to abstract the calibration code

Wyświetl plik

@ -21,42 +21,44 @@
#define VSYNCINT 16
// Field State bits (maintained in r3)
//
// bit 0 indicates mode 7
// bit 1 is the buffer being written to
// bit 2 is the buffer being displayed
// bit 3 is the field type (0 = odd, 1 = even) of the last field
// Control bits (maintained in r3)
#define BIT_MODE7 0x01
#define BIT_PROBE 0x02
#define BIT_CALIBRATE 0x04
#define BIT_NO_DEINT 0x08
#define BIT_OSD 0x10
#define BIT_INITIALIZE 0x20
#define BIT_ELK 0x40
#define BIT_SCANLINES 0x80
#define BIT_FIELD_TYPE 0x100
#define BIT_CLEAR 0x200
#define BIT_VSYNC 0x400
#define BIT_CAL_COUNT 0x800
#define BIT_DEINT_MODE_0 0x100000
#define BIT_DEINT_MODE_1 0x200000
#define BIT_DEBUG 0x400000
// Note, due to a hack, bits 16, 19 and 26 are unavailale
// as the are used for switch change detection
#define OFFSET_LAST_BUFFER 12
#define OFFSET_CURR_BUFFER 14
#define OFFSET_NBUFFERS 17
#define OFFSET_INTERLACE 20
#define BIT_MODE7 0x01 // bit 0, indicates mode 7
#define BIT_PROBE 0x02 // bit 1, indicates the mode is being determined
#define BIT_CALIBRATE 0x04 // bit 2, indicates calibration is happening
#define BIT_NO_DEINT 0x08 // bit 3, indicates all deinterlacing should be disabled
#define BIT_OSD 0x10 // bit 4, indicated the OSD is visible
#define BIT_INITIALIZE 0x20 // bit 5, indicates we should sync to an even frame
#define BIT_ELK 0x40 // bit 6, indicated we are an Electron
#define BIT_SCANLINES 0x80 // bit 7, indicates scan lines should be made visible
#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)
#define OFFSET_LAST_BUFFER 12 // bit 12-13 LAST_BUFFER
#define MASK_LAST_BUFFER (3 << OFFSET_LAST_BUFFER)
#define OFFSET_CURR_BUFFER 14 // bit 14-15 CURR_BUFFER
#define MASK_CURR_BUFFER (3 << OFFSET_CURR_BUFFER)
// bit 16 unavailable (used for switch detection)
#define OFFSET_NBUFFERS 17 // bit 17-18 NBUFFERS
#define MASK_NBUFFERS (3 << OFFSET_NBUFFERS)
// bit 19 unavailable (used for switch detection)
#define OFFSET_INTERLACE 20 // bit 20-21 INTERFACE
#define MASK_INTERLACE (3 << OFFSET_INTERLACE)
#define BIT_NEW_DEINT 0x400000 // bit 22, indicates the new deinterlace algorithm should be used
#define BIT_DEBUG 0x800000 // bit 23, indicated the debug grid should be displayed
// bit 24-25 unused
// bit 26 unavailable (used for switch detection)
// bit 27-31 unused
// R0 return value bits
#define RET_SW1 0x02
#define RET_SW2 0x04

Wyświetl plik

@ -75,15 +75,6 @@ enum {
NUM_INFOS
};
enum {
DEINTERLACE_NONE,
DEINTERLACE_MA1,
DEINTERLACE_MA2,
DEINTERLACE_MA3,
DEINTERLACE_MA4,
NUM_DEINTERLACES
};
static const char *info_names[] = {
"Firmware Version",
"Calibration Summary",
@ -107,10 +98,14 @@ static const char *pllh_names[] = {
static const char *deinterlace_names[] = {
"None",
"Motion Adaptive 1 field",
"Motion Adaptive 2 fields",
"Motion Adaptive 3 fields",
"Motion Adaptive 4 fields",
"Motion Adaptive 1",
"Motion Adaptive 2",
"Motion Adaptive 3",
"Motion Adaptive 4",
"Aligned Motion Adaptive 1",
"Aligned Motion Adaptive 2",
"Aligned Motion Adaptive 3",
"Aligned Motion Adaptive 4"
};
#ifdef MULTI_BUFFER
@ -674,6 +669,10 @@ void osd_init() {
}
}
}
// Disable CPLDv2 specific features for CPLDv1
if (((cpld->get_version() >> VERSION_MAJOR_BIT) & 0x0F) < 2) {
features[F_DEINTERLACE].max = DEINTERLACE_MA4;
}
}
void osd_update(uint32_t *osd_base, int bytes_per_line) {

Wyświetl plik

@ -9,6 +9,19 @@
extern int clock_error_ppm;
enum {
DEINTERLACE_NONE,
DEINTERLACE_MA1,
DEINTERLACE_MA2,
DEINTERLACE_MA3,
DEINTERLACE_MA4,
DEINTERLACE_MA1_NEW,
DEINTERLACE_MA2_NEW,
DEINTERLACE_MA3_NEW,
DEINTERLACE_MA4_NEW,
NUM_DEINTERLACES
};
void osd_init();
void osd_clear();
void osd_set(int line, int attr, char *text);

Wyświetl plik

@ -317,7 +317,27 @@ process_chars_loop_7\@:
tst r3, #(BIT_CALIBRATE | BIT_NO_DEINT)
bne skip_deinterlace\@
tst r3, #BIT_NEW_DEINT // use the new deinterlace algorithm?
bne new_deint\@
// The old deinterlace algorithm only compares odd with odd, and even with even
// It will work with CPLD v1 and CPLD v2, as it requires no character alignment
tst r1, #0x88000000 // test motion flag in last field (R1 finished with after this)
orrne r10, #0x00880000 // set 2nd flag if other field had motion
tst r0, #0x88000000
orrne r10, #0x00008800 // set 3rd flag as old 1st flag
tst r0, #0x00880000
orrne r10, #0x00000088 // set 4th flag as old 2nd flag
eor r0, r0, r10 // compare odd with odd and even with even fields
ands r0, r0, r8 // mask out old flag bits
orrne r10, #0x88000000 // set 1st flag upper and lower half words if different.
b completed_word\@
new_deint\@:
// The new deinterlace algorithm requires mode 7 characters to be word-aligned
// which will only be the case with the CPLD v2 that has the configurable delay
tst r1, #0x80000000 // test motion flag in last field
orrne r10, #0x00800000 // set 2nd flag if other field had motion upper half word

Wyświetl plik

@ -998,10 +998,13 @@ void rgb_to_hdmi_main() {
if (osd_active()) {
flags |= BIT_OSD;
}
if (deinterlace == 0) {
flags |= BIT_NO_DEINT;
if (deinterlace >= DEINTERLACE_MA1 && deinterlace <= DEINTERLACE_MA4) {
flags |= (deinterlace - DEINTERLACE_MA1) << OFFSET_INTERLACE;
} else if (deinterlace >= DEINTERLACE_MA1_NEW && deinterlace <= DEINTERLACE_MA4_NEW) {
flags |= (deinterlace - DEINTERLACE_MA1_NEW) << OFFSET_INTERLACE;
flags |= BIT_NEW_DEINT;
} else {
flags |= (deinterlace - 1) << OFFSET_INTERLACE;
flags |= BIT_NO_DEINT;
}
#ifdef MULTI_BUFFER
flags |= nbuffers << OFFSET_NBUFFERS;