This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch releases/13.0
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/releases/13.0 by this push:
new 18aa9d9af69 video/videomode: Fix EDID parsing and formatting of video
mode dumps
18aa9d9af69 is described below
commit 18aa9d9af69d21575781eb26d4dde00dbfd79664
Author: Lwazi Dube <[email protected]>
AuthorDate: Fri Aug 21 23:12:16 2026 -0400
video/videomode: Fix EDID parsing and formatting of video mode dumps
Fixes several bugs in EDID parsing and consolidates syslog output in
videomode_dump to prevent broken lines.
Specific changes include:
- Corrected bitwise masking for _HACT_HI (0xf0) and _HBLK_HI (0x0f)
to properly extract the upper bits of horizontal active and blanking
timings.
- Multiplied raw EDID pixel clock by 10 to convert it into kHz, matching
the expectation of the videomode struct dotclock field.
- Combined fragmented syslog calls in videomode_dump into a single line
to prevent unwanted newlines from splitting the output across multiple
logs.
Signed-off-by: Lwazi Dube <[email protected]>
---
include/nuttx/video/edid.h | 4 +-
video/videomode/edid_parse.c | 152 +++++++++++++++++++--------------------
video/videomode/videomode_dump.c | 23 +++---
3 files changed, 90 insertions(+), 89 deletions(-)
diff --git a/include/nuttx/video/edid.h b/include/nuttx/video/edid.h
index adbbeaa8183..7ec83ed3ca5 100644
--- a/include/nuttx/video/edid.h
+++ b/include/nuttx/video/edid.h
@@ -387,8 +387,8 @@
#define _HACT_LO(p)
((p)[EDID_DESC_HPIXELS_LSBITS_OFFSET])
#define _HBLK_LO(p) ((p)[EDID_DESC_HBLANK_LSBITS_OFFSET])
-#define _HACT_HI(p) (((p)[EDID_DESC_HMSBITS_OFFSET] &
EDID_DESC_HPIXELS_MSBITS_SHIFT) << 4)
-#define _HBLK_HI(p) (((p)[EDID_DESC_HMSBITS_OFFSET] &
EDID_DESC_HBLANK_MSBITS_SHIFT) << 8)
+#define _HACT_HI(p) (((p)[EDID_DESC_HMSBITS_OFFSET] &
0xf0) << 4)
+#define _HBLK_HI(p) (((p)[EDID_DESC_HMSBITS_OFFSET] &
0x0f) << 8)
#define EDID_DESC_HACTIVE(p) (_HACT_LO(p) | _HACT_HI(p))
#define EDID_DESC_HBLANK(p) (_HBLK_LO(p) | _HBLK_HI(p))
diff --git a/video/videomode/edid_parse.c b/video/videomode/edid_parse.c
index b2ef10607df..a9dfd1903cd 100644
--- a/video/videomode/edid_parse.c
+++ b/video/videomode/edid_parse.c
@@ -138,22 +138,22 @@ static bool edid_std_timing(FAR const uint8_t *stdtim,
info = stdtim[EDID_STDTIMING_INFO_OFFSET];
switch (info & EDID_STDTIMING_ASPECT_MASK)
{
- case EDID_STDTIMING_ASPECT_16_10:
- y = x * 10 / 16;
- break;
-
- case EDID_STDTIMING_ASPECT_4_3:
- y = x * 3 / 4;
- break;
-
- case EDID_STDTIMING_ASPECT_5_4:
- y = x * 4 / 5;
- break;
-
- case EDID_STDTIMING_ASPECT_16_9:
- default:
- y = x * 9 / 16;
- break;
+ case EDID_STDTIMING_ASPECT_16_10:
+ y = x * 10 / 16;
+ break;
+
+ case EDID_STDTIMING_ASPECT_4_3:
+ y = x * 3 / 4;
+ break;
+
+ case EDID_STDTIMING_ASPECT_5_4:
+ y = x * 4 / 5;
+ break;
+
+ case EDID_STDTIMING_ASPECT_16_9:
+ default:
+ y = x * 9 / 16;
+ break;
}
f = (info & ~EDID_STDTIMING_ASPECT_MASK) + 60;
@@ -241,8 +241,8 @@ static bool edid_desc_timing(FAR const uint8_t *desc,
return false;
}
- mode->dotclock = (uint16_t)desc[EDID_DESC_PIXCLOCK_OFFSET] |
- ((uint16_t)desc[EDID_DESC_PIXCLOCK_OFFSET + 1] << 8);
+ mode->dotclock = 10 *((uint16_t)desc[EDID_DESC_PIXCLOCK_OFFSET] |
+ ((uint16_t)desc[EDID_DESC_PIXCLOCK_OFFSET + 1] << 8));
hactive = EDID_DESC_HACTIVE(desc);
hblank = EDID_DESC_HBLANK(desc);
@@ -353,77 +353,77 @@ static void edid_block(FAR struct edid_info_s *edid, FAR
const uint8_t *desc)
switch (desc[EDID_DESC_DESCTYPE])
{
- case EDID_DESCTYPE_SERIALNO:
+ case EDID_DESCTYPE_SERIALNO:
#if 0 /* Not implemented */
- memcpy(edid->edid_serstr, desc + EDID_DESC_ASCII_DATA_OFFSET,
- EDID_DESC_ASCII_DATA_LEN);
- edid->edid_serstr[sizeof(edid->edid_serial) - 1] = 0;
+ memcpy(edid->edid_serstr, desc + EDID_DESC_ASCII_DATA_OFFSET,
+ EDID_DESC_ASCII_DATA_LEN);
+ edid->edid_serstr[sizeof(edid->edid_serial) - 1] = 0;
#endif
- break;
+ break;
- case EDID_DESCTYPE_TEXT:
+ case EDID_DESCTYPE_TEXT:
#if 0 /* Not implemented */
- memcpy(edid->edid_comment, desc + EDID_DESC_ASCII_DATA_OFFSET,
- EDID_DESC_ASCII_DATA_LEN);
- edid->edid_comment[sizeof(edid->edid_comment) - 1] = 0;
+ memcpy(edid->edid_comment, desc + EDID_DESC_ASCII_DATA_OFFSET,
+ EDID_DESC_ASCII_DATA_LEN);
+ edid->edid_comment[sizeof(edid->edid_comment) - 1] = 0;
#endif
- break;
-
- case EDID_DESCTYPE_LIMITS:
- edid->edid_have_range = true;
- edid->edid_range.er_min_vfreq = EDID_DESC_RANGE_MIN_VFREQ(desc);
- edid->edid_range.er_max_vfreq = EDID_DESC_RANGE_MAX_VFREQ(desc);
- edid->edid_range.er_min_hfreq = EDID_DESC_RANGE_MIN_HFREQ(desc);
- edid->edid_range.er_max_hfreq = EDID_DESC_RANGE_MAX_HFREQ(desc);
- edid->edid_range.er_max_clock = EDID_DESC_RANGE_MAX_CLOCK(desc);
-
- if (!EDID_DESC_RANGE_HAVE_GTF2(desc))
- {
- break;
- }
-
- edid->edid_range.er_have_gtf2 = true;
- edid->edid_range.er_gtf2_hfreq = EDID_DESC_RANGE_GTF2_HFREQ(desc);
- edid->edid_range.er_gtf2_c = EDID_DESC_RANGE_GTF2_C(desc);
- edid->edid_range.er_gtf2_m = EDID_DESC_RANGE_GTF2_M(desc);
- edid->edid_range.er_gtf2_j = EDID_DESC_RANGE_GTF2_J(desc);
- edid->edid_range.er_gtf2_k = EDID_DESC_RANGE_GTF2_K(desc);
- break;
-
- case EDID_DESCTYPE_NAME:
+ break;
+
+ case EDID_DESCTYPE_LIMITS:
+ edid->edid_have_range = true;
+ edid->edid_range.er_min_vfreq = EDID_DESC_RANGE_MIN_VFREQ(desc);
+ edid->edid_range.er_max_vfreq = EDID_DESC_RANGE_MAX_VFREQ(desc);
+ edid->edid_range.er_min_hfreq = EDID_DESC_RANGE_MIN_HFREQ(desc);
+ edid->edid_range.er_max_hfreq = EDID_DESC_RANGE_MAX_HFREQ(desc);
+ edid->edid_range.er_max_clock = EDID_DESC_RANGE_MAX_CLOCK(desc);
+
+ if (!EDID_DESC_RANGE_HAVE_GTF2(desc))
+ {
+ break;
+ }
+
+ edid->edid_range.er_have_gtf2 = true;
+ edid->edid_range.er_gtf2_hfreq = EDID_DESC_RANGE_GTF2_HFREQ(desc);
+ edid->edid_range.er_gtf2_c = EDID_DESC_RANGE_GTF2_C(desc);
+ edid->edid_range.er_gtf2_m = EDID_DESC_RANGE_GTF2_M(desc);
+ edid->edid_range.er_gtf2_j = EDID_DESC_RANGE_GTF2_J(desc);
+ edid->edid_range.er_gtf2_k = EDID_DESC_RANGE_GTF2_K(desc);
+ break;
+
+ case EDID_DESCTYPE_NAME:
#if 0 /* Not implemented */
- /* Copy the product name into place */
+ /* Copy the product name into place */
- memcpy(edid->edid_productname,
- desc + EDID_DESC_ASCII_DATA_OFFSET, EDID_DESC_ASCII_DATA_LEN);
+ memcpy(edid->edid_productname,
+ desc + EDID_DESC_ASCII_DATA_OFFSET, EDID_DESC_ASCII_DATA_LEN);
#endif
- break;
+ break;
- case EDID_DESCTYPE_STDTIMING_ID:
- desc += EDID_DESC_STD_TIMING_START_OFFSET;
- for (i = 0; i < EDID_DESC_STD_TIMING_COUNT_OFFSET; i++)
- {
- if (edid_std_timing(desc, &mode))
- {
- /* Does this mode already exist? */
-
- exist_mode = edid_search_mode(edid, &mode);
- if (exist_mode == NULL)
- {
- edid->edid_modes[edid->edid_nmodes] = mode;
- edid->edid_nmodes++;
- }
- }
+ case EDID_DESCTYPE_STDTIMING_ID:
+ desc += EDID_DESC_STD_TIMING_START_OFFSET;
+ for (i = 0; i < EDID_DESC_STD_TIMING_COUNT_OFFSET; i++)
+ {
+ if (edid_std_timing(desc, &mode))
+ {
+ /* Does this mode already exist? */
- desc += 2;
- }
- break;
+ exist_mode = edid_search_mode(edid, &mode);
+ if (exist_mode == NULL)
+ {
+ edid->edid_modes[edid->edid_nmodes] = mode;
+ edid->edid_nmodes++;
+ }
+ }
+
+ desc += 2;
+ }
+ break;
- case EDID_DESCTYPE_WHITEPOINT:
+ case EDID_DESCTYPE_WHITEPOINT:
- /* Not implemented yet */
+ /* Not implemented yet */
- break;
+ break;
}
}
diff --git a/video/videomode/videomode_dump.c b/video/videomode/videomode_dump.c
index 302bd8c85a1..c0cf61fea18 100644
--- a/video/videomode/videomode_dump.c
+++ b/video/videomode/videomode_dump.c
@@ -84,26 +84,27 @@ void videomode_dump(FAR const char *prefix,
{
if (videomode != NULL)
{
- if (prefix != NULL)
+ if (terse)
{
- syslog(LOG_INFO, "%s", prefix);
+ syslog(LOG_INFO, "%s%ux%u @ %luHz",
+ prefix ? prefix : "",
+ videomode->hdisplay, videomode->vdisplay,
+ (unsigned long)videomode_refresh(videomode));
}
-
- syslog(LOG_INFO, "%ux%u @ %luHz",
- videomode->hdisplay, videomode->vdisplay,
- (unsigned long)videomode_refresh(videomode));
-
- if (!terse)
+ else
{
- syslog(LOG_INFO, " (%lu %u %u %u %u %u %u",
+ syslog(LOG_INFO,
+ "%s%ux%u @ %luHz (%lu %u %u %u %u %u %u %s%sH %s%sV)\n",
+ prefix ? prefix : "",
+ videomode->hdisplay, videomode->vdisplay,
+ (unsigned long)videomode_refresh(videomode),
(unsigned long)videomode->dotclock,
videomode->hsync_start,
videomode->hsync_end,
videomode->htotal,
videomode->vsync_start,
videomode->vsync_end,
- videomode->vtotal);
- syslog(LOG_INFO, " %s%sH %s%sV)\n",
+ videomode->vtotal,
videomode->flags & VID_PHSYNC ? "+" : "",
videomode->flags & VID_NHSYNC ? "-" : "",
videomode->flags & VID_PVSYNC ? "+" : "",