[igt-dev] [PATCH i-g-t 2/2] tests/kms_chamelium: add an aspect ratio test

Arkadiusz Hiler arkadiusz.hiler at intel.com
Thu Aug 15 12:21:35 UTC 2019


On Mon, Jul 22, 2019 at 06:01:27PM +0300, Simon Ser wrote:
> 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 at 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);

I think we will get complaints about mixed code and declarations.

Other than that
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler at intel.com>


More information about the igt-dev mailing list