This adds preliminary support for testing HDMI audio integrity with the Chamelium. It aims to use the ALSA and audio IGT libraries to generate a signal with a list of given frequencies, output it through HDMI and check that the correct frequencies (and only those) are detected. The test is currently work in progress and is not working. It is sent only for reference and should not be merged. Signed-off-by: Paul Kocialkowski <paul.kocialkowski@xxxxxxxxxxxxxxx> --- configure.ac | 9 +++-- lib/igt_chamelium.c | 18 ++++++++-- lib/igt_chamelium.h | 6 +++- tests/Makefile.am | 4 +-- tests/chamelium.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 121 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 41ec4d26..dd5d68b6 100644 --- a/configure.ac +++ b/configure.ac @@ -184,6 +184,9 @@ fi PKG_CHECK_MODULES(GSL, [gsl], [gsl=yes], [gsl=no]) AM_CONDITIONAL(HAVE_GSL, [test "x$gsl" = xyes]) +PKG_CHECK_MODULES(ALSA, [alsa], [alsa=yes], [alsa=no]) +AM_CONDITIONAL(HAVE_ALSA, [test "x$alsa" = xyes]) + # for chamelium AC_ARG_ENABLE(chamelium, AS_HELP_STRING([--enable-chamelium], [Enable building of chamelium libraries and tests (default: no)]), @@ -215,13 +218,13 @@ if test "x$enable_chamelium" = xyes; then if test x"$gsl" != xyes; then AC_MSG_ERROR([Failed to find gsl, required by chamelium.]) fi + if test x"$alsa" != xyes; then + AC_MSG_ERROR([Failed to find ALSA, required by chamelium.]) + fi AC_DEFINE(HAVE_CHAMELIUM, 1, [Enable Chamelium support]) fi -PKG_CHECK_MODULES(ALSA, [alsa], [alsa=yes], [alsa=no]) -AM_CONDITIONAL(HAVE_ALSA, [test "x$alsa" = xyes]) - # for audio AC_ARG_ENABLE(audio, AS_HELP_STRING([--enable-audio], [Enable building of audio tests (default: no)]), diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c index dcd8855f..b4d98cd6 100644 --- a/lib/igt_chamelium.c +++ b/lib/igt_chamelium.c @@ -484,14 +484,14 @@ void chamelium_schedule_hpd_toggle(struct chamelium *chamelium, * * Returns: The ID of the EDID uploaded to the chamelium. */ -int chamelium_new_edid(struct chamelium *chamelium, const unsigned char *edid) +int chamelium_new_edid(struct chamelium *chamelium, const unsigned char *edid, int size) { xmlrpc_value *res; struct chamelium_edid *allocated_edid; int edid_id; res = chamelium_rpc(chamelium, NULL, "CreateEdid", "(6)", - edid, EDID_LENGTH); + edid, size); xmlrpc_read_int(&chamelium->env, res, &edid_id); xmlrpc_DECREF(res); @@ -1376,6 +1376,20 @@ igt_crc_t *chamelium_calculate_fb_crc_async_finish(struct chamelium_fb_crc_async return ret; } +void chamelium_start_capturing_audio(struct chamelium *chamelium, + struct chamelium_port *port) +{ + xmlrpc_DECREF(chamelium_rpc(chamelium, port, "StartCapturingAudio", + "(ib)", port->id, true)); +} + +void chamelium_stop_capturing_audio(struct chamelium *chamelium, + struct chamelium_port *port) +{ + xmlrpc_DECREF(chamelium_rpc(chamelium, port, "StopCapturingAudio", + "(i)", port->id)); +} + static unsigned int chamelium_get_port_type(struct chamelium *chamelium, struct chamelium_port *port) { diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h index 2a0fa234..c71a8620 100644 --- a/lib/igt_chamelium.h +++ b/lib/igt_chamelium.h @@ -65,7 +65,7 @@ void chamelium_fire_hpd_pulses(struct chamelium *chamelium, void chamelium_schedule_hpd_toggle(struct chamelium *chamelium, struct chamelium_port *port, int delay_ms, bool rising_edge); -int chamelium_new_edid(struct chamelium *chamelium, const unsigned char *edid); +int chamelium_new_edid(struct chamelium *chamelium, const unsigned char *edid, int size); void chamelium_port_set_edid(struct chamelium *chamelium, struct chamelium_port *port, int edid_id); bool chamelium_port_get_ddc_state(struct chamelium *chamelium, @@ -115,5 +115,9 @@ void chamelium_assert_analog_frame_match_or_dump(struct chamelium *chamelium, void chamelium_crop_analog_frame(struct chamelium_frame_dump *dump, int width, int height); void chamelium_destroy_frame_dump(struct chamelium_frame_dump *dump); +void chamelium_start_capturing_audio(struct chamelium *chamelium, + struct chamelium_port *port); +void chamelium_stop_capturing_audio(struct chamelium *chamelium, + struct chamelium_port *port); #endif /* IGT_CHAMELIUM_H */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 726e2b27..82ca5159 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -138,8 +138,8 @@ vc4_wait_bo_LDADD = $(LDADD) $(DRM_VC4_LIBS) vc4_wait_seqno_CFLAGS = $(AM_CFLAGS) $(DRM_VC4_CFLAGS) vc4_wait_seqno_LDADD = $(LDADD) $(DRM_VC4_LIBS) -chamelium_CFLAGS = $(AM_CFLAGS) $(XMLRPC_CFLAGS) $(LIBUDEV_CFLAGS) -chamelium_LDADD = $(LDADD) $(XMLRPC_LIBS) $(LIBUDEV_LIBS) +chamelium_CFLAGS = $(AM_CFLAGS) $(XMLRPC_CFLAGS) $(LIBUDEV_CFLAGS) $(ALSA_CFLAGS) +chamelium_LDADD = $(LDADD) $(XMLRPC_LIBS) $(LIBUDEV_LIBS) $(ALSA_LIBS) audio_CFLAGS = $(AM_CFLAGS) $(ALSA_CFLAGS) audio_LDADD = $(LDADD) $(ALSA_LIBS) diff --git a/tests/chamelium.c b/tests/chamelium.c index e3d81357..aa33e3c7 100644 --- a/tests/chamelium.c +++ b/tests/chamelium.c @@ -39,6 +39,7 @@ typedef struct { int edid_id; int alt_edid_id; + int audio_edid_id; } data_t; #define HOTPLUG_TIMEOUT 20 /* seconds */ @@ -728,6 +729,82 @@ test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width) igt_hpd_storm_reset(data->drm_fd); } +static int test_frequencies[] = { + 300, + 600, + 1200, + 80000, + 10000, +}; + +static int test_frequencies_count = sizeof(test_frequencies) / sizeof(int); + +static int +output_callback(void *data, short *buffer, int frames) +{ + struct audio_signal *signal = (struct audio_signal *) data; + + audio_signal_fill(signal, buffer, frames); + + return 0; +} + +static void +test_audio_integrity(data_t *data, struct chamelium_port *port, int edid_id) +{ + struct audio_signal *signal; + struct alsa *alsa; + int ret; + int j; + + reset_state(data, port); + + chamelium_port_set_edid(data->chamelium, port, edid_id); + chamelium_plug(data->chamelium, port); + wait_for_connector(data, port, DRM_MODE_CONNECTED); + + alsa = alsa_init(); + igt_assert(alsa); + + ret = alsa_open_output(alsa, "HDMI"); + igt_assert(ret >= 0); + + alsa_configure_output(alsa, 2, 44100); + + signal = audio_signal_init(2, 44100); + igt_assert(signal); + + for (j = 0; j < test_frequencies_count; j++) + audio_signal_add_frequency(signal, + test_frequencies[j]); + + audio_signal_synthesize(signal); + + alsa_register_output_callback(alsa, output_callback, + signal, 1024); + + igt_debug("starting audio capture\n"); + chamelium_start_capturing_audio(data->chamelium, port); + + ret = alsa_run(alsa, 2000); + igt_assert(ret > 0); + + audio_signal_clean(signal); + free(signal); + + igt_debug("stopping audio capture\n"); + chamelium_stop_capturing_audio(data->chamelium, port); + + // TODO: Retrieve audio from Chamelium. + + alsa_close_output(alsa); + + /* TODO: Call audio_signal_detect with each 2048 captured frames + * and assert that at least 3 in a row give a positive result. + */ + +} + #define for_each_port(p, port) \ for (p = 0, port = data.ports[p]; \ p < data.port_count; \ @@ -744,7 +821,9 @@ static data_t data; igt_main { struct chamelium_port *port; - int edid_id, alt_edid_id, p; + int edid_id, alt_edid_id, audio_edid_id, p; + unsigned char *edid; + size_t length; igt_fixture { igt_skip_on_simulation(); @@ -757,11 +836,17 @@ igt_main &data.port_count); edid_id = chamelium_new_edid(data.chamelium, - igt_kms_get_base_edid()); + igt_kms_get_base_edid(), EDID_LENGTH); alt_edid_id = chamelium_new_edid(data.chamelium, - igt_kms_get_alt_edid()); + igt_kms_get_alt_edid(), EDID_LENGTH); + + kmstest_edid_add_audio(igt_kms_get_base_edid(), EDID_LENGTH, + &edid, &length); + audio_edid_id = chamelium_new_edid(data.chamelium, edid, length); + data.edid_id = edid_id; data.alt_edid_id = alt_edid_id; + data.audio_edid_id = audio_edid_id; /* So fbcon doesn't try to reprobe things itself */ kmstest_set_vt_graphics_mode(); @@ -893,6 +978,9 @@ igt_main connector_subtest("hdmi-frame-dump", HDMIA) test_display_frame_dump(&data, port); + + connector_subtest("hdmi-audio-integrity", HDMIA) + test_audio_integrity(&data, port, audio_edid_id); } igt_subtest_group { @@ -944,6 +1032,7 @@ igt_main } igt_fixture { + free(edid); close(data.drm_fd); } } -- 2.14.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx