From: Simon Ser <simon.ser@intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t 2/2] tests/kms_chamelium: add an aspect ratio test
Date: Mon, 22 Jul 2019 18:01:27 +0300 [thread overview]
Message-ID: <20190722150127.3357-3-simon.ser@intel.com> (raw)
In-Reply-To: <20190722150127.3357-1-simon.ser@intel.com>
This test generates an EDID with support for modes tied to a specific aspect
ratio. It then plugs a connector with this EDID and iterates the list of modes
to find the one with the expected aspect ratio flag. The connector is then
enabled and the Chamelium board is used to capture the AVI InfoFrame. The
InfoFrame fields are then checked.
To advertise support for a mode with a specific aspect ratio, sinks add Video
Identification Codes in the CEA extension. The VIC chosen by the source is
contained in the AVI InfoFrame. The InfoFrame also contains a picture aspect
ratio field, but it's only able to indicate whether the aspect ratio is 16:9 or
4:3.
For now the test is only enabled for HDMI. I've tried to make it work on DP
too, but after reading the kernel code it seems like we don't support AVI
InfoFrames on DP.
Signed-off-by: Simon Ser <simon.ser@intel.com>
---
tests/kms_chamelium.c | 169 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 168 insertions(+), 1 deletion(-)
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 913a4cd8506d..4b41e2cad9d0 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -41,8 +41,9 @@ enum test_edid {
TEST_EDID_ALT,
TEST_EDID_HDMI_AUDIO,
TEST_EDID_DP_AUDIO,
+ TEST_EDID_ASPECT_RATIO,
};
-#define TEST_EDID_COUNT 4
+#define TEST_EDID_COUNT 5
typedef struct {
struct chamelium *chamelium;
@@ -862,6 +863,167 @@ static void test_mode_timings(data_t *data, struct chamelium_port *port)
drmModeFreeConnector(connector);
}
+/* Set of Video Identification Codes advertised in the EDID */
+static const uint8_t edid_ar_svds[] = {
+ 16, /* 1080p @ 60Hz, 16:9 */
+};
+
+struct vic_mode {
+ int hactive, vactive;
+ int vrefresh; /* Hz */
+ uint32_t picture_ar;
+};
+
+/* Maps Video Identification Codes to a mode */
+static const struct vic_mode vic_modes[] = {
+ [16] = {
+ .hactive = 1920,
+ .vactive = 1080,
+ .vrefresh = 60,
+ .picture_ar = DRM_MODE_PICTURE_ASPECT_16_9,
+ },
+};
+
+/* Maps aspect ratios to their mode flag */
+static const uint32_t mode_ar_flags[] = {
+ [DRM_MODE_PICTURE_ASPECT_16_9] = DRM_MODE_FLAG_PIC_AR_16_9,
+};
+
+static enum infoframe_avi_picture_aspect_ratio
+get_infoframe_avi_picture_ar(uint32_t aspect_ratio)
+{
+ /* The AVI picture aspect ratio field only supports 4:3 and 16:9 */
+ switch (aspect_ratio) {
+ case DRM_MODE_PICTURE_ASPECT_4_3:
+ return INFOFRAME_AVI_PIC_AR_4_3;
+ case DRM_MODE_PICTURE_ASPECT_16_9:
+ return INFOFRAME_AVI_PIC_AR_16_9;
+ default:
+ return INFOFRAME_AVI_PIC_AR_UNSPECIFIED;
+ }
+}
+
+static bool vic_mode_matches_drm(const struct vic_mode *vic_mode,
+ drmModeModeInfo *drm_mode)
+{
+ uint32_t ar_flag = mode_ar_flags[vic_mode->picture_ar];
+
+ return vic_mode->hactive == drm_mode->hdisplay &&
+ vic_mode->vactive == drm_mode->vdisplay &&
+ vic_mode->vrefresh == drm_mode->vrefresh &&
+ ar_flag == (drm_mode->flags & DRM_MODE_FLAG_PIC_AR_MASK);
+}
+
+static const struct edid *get_aspect_ratio_edid(void)
+{
+ static unsigned char raw_edid[2 * EDID_BLOCK_SIZE] = {0};
+ struct edid *edid;
+ struct edid_ext *edid_ext;
+ struct edid_cea *edid_cea;
+ char *cea_data;
+ struct edid_cea_data_block *block;
+ size_t cea_data_size = 0, vsdb_size;
+ const struct cea_vsdb *vsdb;
+
+ edid = (struct edid *) raw_edid;
+ memcpy(edid, igt_kms_get_base_edid(), sizeof(struct edid));
+ edid->extensions_len = 1;
+ edid_ext = &edid->extensions[0];
+ edid_cea = &edid_ext->data.cea;
+ cea_data = edid_cea->data;
+
+ /* The HDMI VSDB advertises support for InfoFrames */
+ block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
+ vsdb = cea_vsdb_get_hdmi_default(&vsdb_size);
+ cea_data_size += edid_cea_data_block_set_vsdb(block, vsdb,
+ vsdb_size);
+
+ /* Short Video Descriptor */
+ block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
+ cea_data_size += edid_cea_data_block_set_svd(block, edid_ar_svds,
+ sizeof(edid_ar_svds));
+
+ assert(cea_data_size <= sizeof(edid_cea->data));
+
+ edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
+
+ edid_update_checksum(edid);
+
+ return edid;
+}
+
+static void test_display_aspect_ratio(data_t *data, struct chamelium_port *port)
+{
+ igt_output_t *output;
+ igt_plane_t *primary;
+ drmModeConnector *connector;
+ drmModeModeInfo *mode;
+ int fb_id, i;
+ struct igt_fb fb;
+ bool found, ok;
+ struct chamelium_infoframe *infoframe;
+ struct infoframe_avi infoframe_avi;
+ uint8_t vic = 16; /* TODO: test more VICs */
+
+ igt_require(chamelium_supports_get_last_infoframe(data->chamelium));
+
+ reset_state(data, port);
+
+ output = prepare_output(data, port, TEST_EDID_ASPECT_RATIO);
+ connector = chamelium_port_get_connector(data->chamelium, port, false);
+ primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+ igt_assert(primary);
+
+ const struct vic_mode *vic_mode = &vic_modes[vic];
+ uint32_t aspect_ratio = vic_mode->picture_ar;
+
+ found = false;
+ igt_assert(connector->count_modes > 0);
+ for (i = 0; i < connector->count_modes; i++) {
+ mode = &connector->modes[i];
+
+ if (vic_mode_matches_drm(vic_mode, mode)) {
+ found = true;
+ break;
+ }
+ }
+ igt_assert_f(found,
+ "Failed to find mode with the correct aspect ratio\n");
+
+ fb_id = igt_create_color_pattern_fb(data->drm_fd,
+ mode->hdisplay, mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ LOCAL_DRM_FORMAT_MOD_NONE,
+ 0, 0, 0, &fb);
+ igt_assert(fb_id > 0);
+
+ enable_output(data, port, output, mode, &fb);
+
+ infoframe = chamelium_get_last_infoframe(data->chamelium, port,
+ CHAMELIUM_INFOFRAME_AVI);
+ igt_assert_f(infoframe, "AVI InfoFrame not received\n");
+
+ ok = infoframe_avi_parse(&infoframe_avi, infoframe->version,
+ infoframe->payload, infoframe->payload_size);
+ igt_assert_f(ok, "Failed to parse AVI InfoFrame\n");
+
+ enum infoframe_avi_picture_aspect_ratio frame_ar =
+ get_infoframe_avi_picture_ar(aspect_ratio);
+
+ igt_debug("Checking AVI InfoFrame\n");
+ igt_debug("Picture aspect ratio: got %d, expected %d\n",
+ infoframe_avi.picture_aspect_ratio, frame_ar);
+ igt_debug("Video Identification Code (VIC): got %d, expected %d\n",
+ infoframe_avi.vic, vic);
+
+ igt_assert(infoframe_avi.picture_aspect_ratio == frame_ar);
+ igt_assert(infoframe_avi.vic == vic);
+
+ chamelium_infoframe_destroy(infoframe);
+ igt_remove_fb(data->drm_fd, &fb);
+ drmModeFreeConnector(connector);
+}
+
/* Playback parameters control the audio signal we synthesize and send */
#define PLAYBACK_CHANNELS 2
@@ -2208,6 +2370,8 @@ static const struct edid *get_edid(enum test_edid edid)
return igt_kms_get_hdmi_audio_edid();
case TEST_EDID_DP_AUDIO:
return igt_kms_get_dp_audio_edid();
+ case TEST_EDID_ASPECT_RATIO:
+ return get_aspect_ratio_edid();
}
assert(0); /* unreachable */
}
@@ -2487,6 +2651,9 @@ igt_main
connector_subtest("hdmi-audio-edid", HDMIA)
test_display_audio_edid(&data, port,
TEST_EDID_HDMI_AUDIO);
+
+ connector_subtest("hdmi-aspect-ratio", HDMIA)
+ test_display_aspect_ratio(&data, port);
}
igt_subtest_group {
--
2.22.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
next prev parent reply other threads:[~2019-07-22 15:07 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-22 15:01 [igt-dev] [PATCH i-g-t 0/2] Add an HDMI aspect ratio test Simon Ser
2019-07-22 15:01 ` [igt-dev] [PATCH i-g-t 1/2] lib/igt_infoframe: add support for AVI InfoFrames Simon Ser
2019-08-15 11:30 ` Arkadiusz Hiler
2019-08-15 11:54 ` Ser, Simon
2019-07-22 15:01 ` Simon Ser [this message]
2019-08-15 12:21 ` [igt-dev] [PATCH i-g-t 2/2] tests/kms_chamelium: add an aspect ratio test Arkadiusz Hiler
2019-08-15 11:17 ` [igt-dev] ✓ Fi.CI.BAT: success for Add an HDMI aspect ratio test (rev2) Patchwork
2019-08-16 2:32 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190722150127.3357-3-simon.ser@intel.com \
--to=simon.ser@intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox