Skip to contentSkip to conversation

tests/kms_chamelium: add dp-audio test

PATCH Superseded Simon Ser 3 participants 22 messages Apr 17, 2019 – Apr 25, 2019

Subsystems (2)

v6 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Simon Ser

author
#0 lore raw

v6 cover tests/kms_chamelium: add dp-audio test

Changes in v6:

- Rebased the whole series
- Reword the first commit to include a note about the short -> uint16_t change
- Add a HAX commit to temporarily ad dp-audio to fast-feedback (do not merge)

Simon Ser (7):
tests/kms_chamelium: add dp-audio test tests/kms_chamelium: capture audio data in real-time tests/kms_chamelium: test we receive a signal from both audio channels tests/kms_chamelium: test audio channels are not mixed up tests/kms_chamelium: run audio test with multiple sampling rates lib/igt_edid: add support for Short Audio Descriptors
HAX: add dp-audio test to fast-feedback

 docs/audio.txt                        |  45 --
 docs/chamelium.txt                    |  34 +-
 lib/igt.h                             |   1 +
 lib/igt_alsa.c                        |  83 +++-
 lib/igt_alsa.h                        |   1 +
 lib/igt_audio.c                       | 428 +++++++++++++------
 lib/igt_audio.h                       |  19 +-
 lib/igt_aux.c                         |  31 ++
 lib/igt_aux.h                         |   1 +
 lib/igt_chamelium.c                   | 161 ++++++++
 lib/igt_chamelium.h                   |  17 +
 lib/igt_chamelium_stream.c            | 572 ++++++++++++++++++++++++++
 lib/igt_chamelium_stream.h            |  50 +++
 lib/igt_edid.c                        |  73 +++-
 lib/igt_edid.h                        |  82 +++-
 lib/meson.build                       |   5 +-
 meson.build                           |  52 +--
 meson_options.txt                     |   6 -
 tests/audio.c                         | 193 ---------
 tests/intel-ci/fast-feedback.testlist |   1 +
 tests/kms_chamelium.c                 | 352 +++++++++++++++-
 tests/meson.build                     |   9 +-
 22 files changed, 1756 insertions(+), 460 deletions(-)
 delete mode 100644 docs/audio.txt
 create mode 100644 lib/igt_chamelium_stream.c
 create mode 100644 lib/igt_chamelium_stream.h
 delete mode 100644 tests/audio.c
Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#1 lore raw

PATCH v6 1/7 tests/kms_chamelium: add dp-audio test

This new test ensures DisplayPort audio works by using the Chamelium.

It enables the DisplayPort output and sends an audio signal containing a set of frequencies we choose to all HDMI/DisplayPort audio devices. It starts recording audio on the Chamelium device and uses the stream server to retrieve captured audio pages. It then checks that the capture audio signal contains the frequencies we sent, and only those, by computing a FFT.

A new library has been added to libigt to communicate with the stream server. It implements a simple custom TCP protocol.

In case the test fails, a WAV file with the captured data is saved on disk.

Right now the test has a few limitations:

- Only the first channel is checked
- IGT only generates audio with a single sampling rate (48 KHz)
- Audio data is not captured in real-time

These limitations will be lifted in future patches.

PulseAudio must not run during the tests since ALSA is used directly. To ensure this, edit /etc/pulse/client.conf and add autospawn=no. Then run pulseaudio --kill.

This commit deletes the existing audio tests. They weren't run and required an exotic configuration (HDMI audio splitter, dummy HDMI sink and a line-in port on the DUT).

This patch also changes lib/igt_audio to use uint16_t instead of short. The rationale is:

- The standard says a short is at least 16 bit wide, but a short can be larger (in practice it won't happen, but better use types correctly)
- It makes it clearer that the audio format is S16_LE, since "16" is in the type name.

This patch depends on the following Chameleon bugs:

- https://crbug.com/948060
- https://crbug.com/950857

---
 docs/audio.txt             |  45 ---
 docs/chamelium.txt         |  34 ++-
 lib/igt.h                  |   1 +
 lib/igt_alsa.c             |  42 ++-
 lib/igt_alsa.h             |   1 +
 lib/igt_audio.c            | 313 ++++++++++++++------
 lib/igt_audio.h            |  12 +-
 lib/igt_aux.c              |  31 ++
 lib/igt_aux.h              |   1 +
 lib/igt_chamelium.c        | 101 +++++++
 lib/igt_chamelium.h        |  11 +
 lib/igt_chamelium_stream.c | 589 +++++++++++++++++++++++++++++++++++++
 lib/igt_chamelium_stream.h |  52 ++++
 lib/meson.build            |   5 +-
 meson.build                |  52 ++--
 meson_options.txt          |   6 -
 tests/audio.c              | 193 ------------
 tests/kms_chamelium.c      | 276 ++++++++++++++++-
 tests/meson.build          |   9 +-
 19 files changed, 1382 insertions(+), 392 deletions(-)
 delete mode 100644 docs/audio.txt
 create mode 100644 lib/igt_chamelium_stream.c
 create mode 100644 lib/igt_chamelium_stream.h
 delete mode 100644 tests/audio.c
docs/audio.txt deleted +0 -45
deleted file mode 100644
index 158ad5d1..00000000
@@ -1,45 +0,0 @@
-Audio Support in IGT
-====================
-
-This document provides information and instructions about audio support in IGT.
-
-Introduction
-------------
-
-The audio test is aimed at testing the audio features of display connectors,
-such as HDMI.
-
-Test setup
-----------
-
-The setup required for the audio test consists of using an HDMI-VGA adapter with
-an audio-out 3.5 mm jack to extract the audio from the HDMI interface.
-The audio-out jack is connected back to the device-under-test's line-in.
-
-Depending on the behavior of the adapter, it may be necessary to connect a
-ghost VGA dongle to it (in order to emulate a connected display) to enable the
-audio output. There are guides available detailing how to build these.
-
-When executed, the test will automatically send the test audio signal to all
-ALSA audio HDMI outputs and record from the standard ALSA capture device.
-
-Configuration
--------------
-
-In order to deploy the test, ALSA controls have to be configured to set the
-ALSA capture source to line-in. On Intel x86 systems, this can be achieved
-with the following calls to the amixer utility:
-# amixer sset Line 31 on
-# amixer sset "Input Source" Line
-
-It is then useful to store the ALSA state permanently with the alsactl utility:
-# alsactl store
-
-These settings can be restored with the alsactl utility:
-# alsactl restore
-
-It is desirable to ensure that the alsa-restore and alsa-state systemd services
-are enabled to do this job automatically, especially in the case of an
-automated testing system:
-# systemctl enable alsa-restore
-# systemctl enable alsa-state
docs/chamelium.txt +28 -6
index 0cabcdc6..5cc85d6e 100644
@@ -139,6 +139,23 @@ $ make remote-install CHAMELEON_HOST=192.168.72.1
 
 The process requires the Chamelium to be connected to the Internet to succeed.
 
+Audio Capture
+-------------
+
+The Chamelium supports audio capture. IGT tests take advantage of the
+Chamelium streaming server to download audio samples from the Chamelium.
+
+IGT needs direct access to audio devices through ALSA, so PulseAudio needs to
+be stopped (otherwise audio tests will automatically get skipped). To make sure
+PulseAudio isn't running:
+
+- Edit /etc/pulse/client.conf and add autospawn=no
+- Run `pulseaudio --kill` (if it succeeds, it means PulseAudio was running)
+- Make sure a DE that automatically spawns PulseAudio isn't running
+
+In case a test fails, the raw captured audio files will be dumped in a WAV
+file.
+
 Contributing Changes to the Daemon
 ----------------------------------
 
@@ -146,10 +163,11 @@ Contributions to the Chamelium daemon, just like any contribution to ChromiumOS,
 are submitted and reviewed at: https://chromium-review.googlesource.com/
 
 The ChromiumOS project provides an extensive developer guide:
-https://www.chromium.org/chromium-os/developer-guide that assumes running within
-the ChromiumOS build system. Since this is likely not the case for contributing
-to the Chamelium daemon, only the part about uploading changes is relevant:
-https://www.chromium.org/chromium-os/developer-guide#TOC-Upload-your-changes-and-get-a-code-review
+https://chromium.googlesource.com/chromiumos/docs/+/master/developer_guide.md
+It assumes running within the ChromiumOS build system. Since this is likely not
+the case for contributing to the Chamelium daemon, only the part about
+uploading changes is relevant:
+https://chromium.googlesource.com/chromiumos/docs/+/master/developer_guide.md#Upload-your-changes-and-get-a-code-review
 
 Most of the process is about using the Gerrit web interface for submitting and
 having the change reviewed and not forgetting the Change-Id, TEST= and BUG=
@@ -162,7 +180,7 @@ Support for the Chamelium platform in IGT is found in the following places:
 * lib/igt_chamelium.c: library with Chamelium-related helpers
 * tests/kms_chamelium.c: sub-tests using the Chamelium
 
-As of late August 2017, the following features are tested by IGT:
+As of early April 2019, the following features are tested by IGT:
 * Pixel-by-pixel frame integrity tests for DP and HDMI
 * Error-trend-based frame integrity tests for VGA
 * CRC-based frame integrity tests for DP and HDMI
@@ -173,6 +191,7 @@ As of late August 2017, the following features are tested by IGT:
   each interface or combined
 * EDID display identifier integrity check for all interfaces
 * EDID display identifier change during suspend for all interfaces
+* Audio Fourier-based tests for DP at 48KHz
 
 Future Developments
 -------------------
@@ -180,7 +199,10 @@ Future Developments
 With the current generation of the hardware platform, support for testing a
 number of additional display features could be included as future developments,
 including:
-* Audio capture from HDMI and DP
+* Audio capture from HDMI
+* Check all channels are independent from each other
+* Playback using more than 2 channels, different sampling rates and different
+  sample sizes
 * High-bandwidth Digital Content Protection (HDCP) streaming to the display
 * Remote control forwarding (CEC) sent from the display
 * YUV colorspace for HDMI, instead of RGB
lib/igt.h +1 -0
index 6654a659..5852d557 100644
@@ -43,6 +43,7 @@
 #include "igt_stats.h"
 #ifdef HAVE_CHAMELIUM
 #include "igt_chamelium.h"
+#include "igt_chamelium_stream.h"
 #endif
 #include "instdone.h"
 #include "intel_batchbuffer.h"
lib/igt_alsa.c +38 -4

91 lines not on this page · raw message

lib/igt_alsa.h +1 -0
index 50795130..5c804b46 100644
@@ -33,6 +33,7 @@
 
 struct alsa;
 
+bool alsa_has_exclusive_access(void);
 struct alsa *alsa_init(void);
 int alsa_open_output(struct alsa *alsa, const char *device_name);
 int alsa_open_input(struct alsa *alsa, const char *device_name);
lib/igt_audio.c +227 -86

365 lines not on this page · raw message

lib/igt_audio.h +9 -3
index b3b658a4..4aa43e69 100644
@@ -30,6 +30,7 @@
 #include "config.h"
 
 #include <stdbool.h>
+#include <stdint.h>
 
 struct audio_signal;
 
@@ -37,8 +38,13 @@ struct audio_signal *audio_signal_init(int channels, int sampling_rate);
 int audio_signal_add_frequency(struct audio_signal *signal, int frequency);
 void audio_signal_synthesize(struct audio_signal *signal);
 void audio_signal_clean(struct audio_signal *signal);
-void audio_signal_fill(struct audio_signal *signal, short *buffer, int frames);
-bool audio_signal_detect(struct audio_signal *signal, int channels,
-			 int sampling_rate, short *buffer, int frames);
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames);
+bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
+			 double *data, size_t data_len);
+size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
+				    int32_t *src, size_t src_len,
+				    int n_channels, int channel);
+int audio_create_wav_file_s32_le(const char *qualifier, uint32_t sample_rate,
+				 uint16_t channels, char **path);
 
 #endif
lib/igt_aux.c +31 -0
index 05528352..3dd68d95 100644
@@ -1259,6 +1259,37 @@ void igt_set_module_param_int(const char *name, int val)
 	igt_set_module_param(name, str);
 }
 
+/**
+ * igt_is_process_running:
+ * @comm: Name of process in the form found in /proc/pid/comm (limited to 15
+ * chars)
+ *
+ * Returns: true in case the process has been found, false otherwise.
+ *
+ * This function checks in the process table for an entry with the name @comm.
+ */
+int igt_is_process_running(const char *comm)
+{
+	PROCTAB *proc;
+	proc_t *proc_info;
+	bool found = false;
+
+	proc = openproc(PROC_FILLCOM | PROC_FILLSTAT);
+	igt_assert(proc != NULL);
+
+	while ((proc_info = readproc(proc, NULL))) {
+		if (!strncasecmp(proc_info->cmd, comm, sizeof(proc_info->cmd))) {
+			freeproc(proc_info);
+			found = true;
+			break;
+		}
+		freeproc(proc_info);
+	}
+
+	closeproc(proc);
+	return found;
+}
+
 /**
  * igt_terminate_process:
  * @sig: Signal to send
lib/igt_aux.h +1 -0
index 55392790..dbd88b67 100644
@@ -279,6 +279,7 @@ bool igt_allow_unlimited_files(void);
 void igt_set_module_param(const char *name, const char *val);
 void igt_set_module_param_int(const char *name, int val);
 
+int igt_is_process_running(const char *comm);
 int igt_terminate_process(int sig, const char *comm);
 void igt_lsof(const char *dpath);
 
lib/igt_chamelium.c +101 -0

113 lines not on this page · raw message

lib/igt_chamelium.h +11 -0
index 233ead85..047f8c5d 100644
@@ -53,6 +53,12 @@ enum chamelium_check {
 	CHAMELIUM_CHECK_CRC,
 };
 
+struct chamelium_audio_file {
+	char *path;
+	int rate; /* Hz */
+	int channels;
+};
+
 struct chamelium *chamelium_init(int drm_fd);
 void chamelium_deinit(struct chamelium *chamelium);
 void chamelium_reset(struct chamelium *chamelium);
@@ -100,6 +106,10 @@ void chamelium_start_capture(struct chamelium *chamelium,
 void chamelium_stop_capture(struct chamelium *chamelium, int frame_count);
 void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 		       int x, int y, int w, int h, int frame_count);
+void chamelium_start_capturing_audio(struct chamelium *chamelium,
+				    struct chamelium_port *port, bool save_to_file);
+struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
+							    struct chamelium_port *port);
 igt_crc_t *chamelium_read_captured_crcs(struct chamelium *chamelium,
 					int *frame_count);
 struct chamelium_frame_dump *chamelium_read_captured_frame(struct chamelium *chamelium,
@@ -131,5 +141,6 @@ void chamelium_assert_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_destroy_audio_file(struct chamelium_audio_file *audio_file);
 
 #endif /* IGT_CHAMELIUM_H */
lib/igt_chamelium_stream.c new file +589 -0

589 lines not on this page · raw message

lib/igt_chamelium_stream.h new file +52 -0

52 lines not on this page · raw message

lib/meson.build +3 -2
index 20c0e3e6..16e1ae21 100644
@@ -93,7 +93,7 @@ if valgrind.found()
 endif
 
 if gsl.found()
-	lib_deps += [ gsl ]
+	lib_deps += gsl
 	lib_sources += [ 'igt_frame.c', 'igt_audio.c' ]
 endif
 
@@ -102,9 +102,10 @@ if alsa.found()
 	lib_sources += 'igt_alsa.c'
 endif
 
-if chamelium.found()
+if chamelium_found
 	lib_deps += chamelium
 	lib_sources += 'igt_chamelium.c'
+	lib_sources += 'igt_chamelium_stream.c'
 endif
 
 srcdir = join_paths(meson.source_root(), 'tests')
meson.build +19 -33

89 lines not on this page · raw message

meson_options.txt +0 -6
index 0cd3b350..888efe56 100644
@@ -10,12 +10,6 @@ option('overlay_backends',
        choices : [ 'auto', 'x', 'xv' ],
        description : 'Overlay backends to enable')
 
-option('build_audio',
-       type : 'combo',
-       value : 'auto',
-       choices : ['auto', 'true', 'false'],
-       description : 'Build audio test')
-
 option('build_chamelium',
        type : 'combo',
        value : 'auto',
tests/audio.c deleted +0 -193

193 lines not on this page · raw message

tests/kms_chamelium.c +270 -6

324 lines not on this page · raw message

tests/meson.build +1 -8
index e3c8b07f..711979b4 100644
@@ -239,20 +239,13 @@ if libdrm_nouveau.found()
 	test_deps += libdrm_nouveau
 endif
 
-if _build_chamelium and chamelium.found()
+if chamelium_found
 	test_progs += [
 		'kms_chamelium',
 	]
 	test_deps += chamelium
 endif
 
-if _build_audio and alsa.found() and gsl.found()
-	test_progs += [
-		'audio',
-	]
-	test_deps += alsa
-endif
-
 test_executables = []
 test_list = []
 
Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#2 lore raw

PATCH v6 2/7 tests/kms_chamelium: capture audio data in real-time

In reply to Simon Ser

Before this patch, the audio test first sends an audio signal for 2s, and then checks whether the captured signal matches.

This patch makes it so we send and check the signal in parallel. Thus we can stop the test as soon as we receive the correct signal. This saves ~2s per audio test.

---
 lib/igt_alsa.c        | 15 +++++++-------
 tests/kms_chamelium.c | 47 +++++++++++++++++++++++++++++++++----------
 2 files changed, 43 insertions(+), 19 deletions(-)
lib/igt_alsa.c +7 -8
index 22089881..fc6d336b 100644
@@ -497,7 +497,8 @@ void alsa_register_input_callback(struct alsa *alsa,
 /**
  * alsa_run:
  * @alsa: The target alsa structure
- * @duration_ms: The maximum duration of the run in milliseconds
+ * @duration_ms: The maximum duration of the run in milliseconds, or -1 for an
+ * infinite duration.
  *
  * Run ALSA playback and capture on the input and output devices for at
  * most @duration_ms milliseconds, calling the registered callbacks when needed.
@@ -545,7 +546,7 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 	do {
 		reached = true;
 
-		if (output_total < output_limit) {
+		if (output_limit < 0 || output_total < output_limit) {
 			reached = false;
 
 			if (!output_ready) {
@@ -607,7 +608,8 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 
 		}
 
-		if (alsa->input_callback && input_total < input_limit) {
+		if (alsa->input_callback &&
+		    (input_limit < 0 || input_total < input_limit)) {
 			reached = false;
 
 			if (input_count == input_trigger) {
@@ -660,11 +662,8 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 	ret = 0;
 
 complete:
-	if (output_buffer)
-		free(output_buffer);
-
-	if (input_buffer)
-		free(input_buffer);
+	free(output_buffer);
+	free(input_buffer);
 
 	return ret;
 }
tests/kms_chamelium.c +36 -11

98 lines not on this page · raw message

Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Reviewed-by on v6 2/7
#3 lore raw

Re: [igt-dev] [PATCH i-g-t v6 2/7] tests/kms_chamelium: capture audio data in real-time

Quoted 6 lines · Simon Ser

Before this patch, the audio test first sends an audio signal for 2s, and then checks whether the captured signal matches.

This patch makes it so we send and check the signal in parallel. Thus we can stop the test as soon as we receive the correct signal. This saves ~2s per audio test.

Given that run_audio_thread is the one calling the callback, we should not have coherency issues.

This patch is:

Quoted 154 lines
---
 lib/igt_alsa.c        | 15 +++++++-------
 tests/kms_chamelium.c | 47 +++++++++++++++++++++++++++++++++----------
 2 files changed, 43 insertions(+), 19 deletions(-)
lib/igt_alsa.c +7 -8
index 22089881..fc6d336b 100644
@@ -497,7 +497,8 @@ void alsa_register_input_callback(struct alsa *alsa,
 /**
  * alsa_run:
  * @alsa: The target alsa structure
- * @duration_ms: The maximum duration of the run in milliseconds
+ * @duration_ms: The maximum duration of the run in milliseconds, or -1 for an
+ * infinite duration.
  *
  * Run ALSA playback and capture on the input and output devices for at
  * most @duration_ms milliseconds, calling the registered callbacks when needed.
@@ -545,7 +546,7 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 	do {
 		reached = true;
 
-		if (output_total < output_limit) {
+		if (output_limit < 0 || output_total < output_limit) {
 			reached = false;
 
 			if (!output_ready) {
@@ -607,7 +608,8 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 
 		}
 
-		if (alsa->input_callback && input_total < input_limit) {
+		if (alsa->input_callback &&
+		    (input_limit < 0 || input_total < input_limit)) {
 			reached = false;
 
 			if (input_count == input_trigger) {
@@ -660,11 +662,8 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 	ret = 0;
 
 complete:
-	if (output_buffer)
-		free(output_buffer);
-
-	if (input_buffer)
-		free(input_buffer);
+	free(output_buffer);
+	free(input_buffer);
 
 	return ret;
 }
tests/kms_chamelium.c +29 -11
index a712250a..014a22b3 100644
@@ -29,7 +29,9 @@
 #include "igt_vc4.h"
 
 #include <fcntl.h>
+#include <pthread.h>
 #include <string.h>
+#include <stdatomic.h>
 
 typedef struct {
 	struct chamelium *chamelium;
@@ -719,7 +721,7 @@ test_display_frame_dump(data_t *data, struct chamelium_port *port)
 /* Capture paremeters control the audio signal we receive */
 #define CAPTURE_SAMPLES 2048
 
-#define AUDIO_DURATION 2000 /* ms */
+#define AUDIO_TIMEOUT 2000 /* ms */
 /* A streak of 3 gives confidence that the signal is good. */
 #define MIN_STREAK 3
 
@@ -746,14 +748,28 @@ static int test_frequencies[] = {
 
 static int test_frequencies_count = sizeof(test_frequencies) / sizeof(int);
 
+struct audio_state {
+	struct audio_signal *signal;
+	atomic_bool run;
+};
+
 static int
-output_callback(void *data, short *buffer, int frames)
+audio_output_callback(void *data, short *buffer, int frames)
 {
-	struct audio_signal *signal = (struct audio_signal *) data;
+	struct audio_state *state = data;
+
+	audio_signal_fill(state->signal, buffer, frames);
 
-	audio_signal_fill(signal, buffer, frames);
+	return state->run ? 0 : -1;
+}
+
+static void *
+run_audio_thread(void *data)
+{
+	struct alsa *alsa = data;
 
-	return 0;
+	alsa_run(alsa, -1);
+	return NULL;
 }
 
 static bool
@@ -774,6 +790,8 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	char dump_suffix[64];
 	char *dump_path = NULL;
 	int dump_fd = -1;
+	pthread_t thread;
+	struct audio_state state = {};
 
 	if (!alsa_test_output_configuration(alsa, playback_channels,
 					    playback_rate))
@@ -811,15 +829,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		audio_signal_add_frequency(signal, test_frequencies[i]);
 	audio_signal_synthesize(signal);
 
-	alsa_register_output_callback(alsa, output_callback, signal,
+	state.signal = signal;
+	state.run = true;
+	alsa_register_output_callback(alsa, audio_output_callback, &state,
 				      PLAYBACK_SAMPLES);
 
-	/* TODO: detect signal in real-time */
-	ret = alsa_run(alsa, AUDIO_DURATION);
+	/* Start playing audio */
+	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
-	alsa_close_output(alsa);
-
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -836,7 +854,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	streak = 0;
 	msec = 0;
 	i = 0;
-	while (streak < MIN_STREAK && msec < AUDIO_DURATION) {
+	while (streak < MIN_STREAK && msec < AUDIO_TIMEOUT) {
 		ok = chamelium_stream_receive_realtime_audio(stream,
 							     &page_count,
 							     &recv, &recv_len);
@@ -871,6 +889,13 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		i++;
 	}
 

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 901

Quoted 10 lines
tests/kms_chamelium.c +7 -0
+	igt_debug("Stopping audio playback\n");
+	state.run = false;
+	ret = pthread_join(thread, NULL);
+	igt_assert(ret == 0);
+
+	alsa_close_output(alsa);
+
 	if (dump_fd >= 0) {
 		close(dump_fd);
 		if (streak == MIN_STREAK) {

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#4 lore raw

PATCH v6 3/7 tests/kms_chamelium: test we receive a signal from both audio channels

In reply to Simon Ser

This commit updates the audio test to make sure we receive a signal from both audio channels. However this commit doesn't check that left and right channels are not swapped. Such a check requires some more work (because the Chamelium device does swap left and right channels) and will be implemented in a future commit.

This commit adds a new channel argument to audio_signal_add_frequency, to add a frequency to a single channel only.

Some light refactoring has been performed (a proper audio_signal_deinit function has been introduced) and logging has been improved.

---
 lib/igt_alsa.c        |  26 +++++++--
 lib/igt_audio.c       | 119 +++++++++++++++++++++++++-----------------
 lib/igt_audio.h       |  11 ++--
 tests/kms_chamelium.c |  56 ++++++++++++--------
 4 files changed, 137 insertions(+), 75 deletions(-)
lib/igt_alsa.c +23 -3
index fc6d336b..a478686a 100644
@@ -182,6 +182,8 @@ static char *alsa_resolve_indentifier(const char *device_name, int skip)
 					continue;
 				}
 
+				igt_debug("Matched device \"%s\"\n", pcm_name);
+
 				snprintf(name, sizeof(name), "hw:%d,%d", card,
 					 dev);
 
@@ -329,6 +331,9 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 {
 	snd_pcm_hw_params_t *params;
 	int ret;
+	unsigned int min_channels, max_channels;
+	unsigned int min_rate, max_rate;
+	int min_rate_dir, max_rate_dir;
 
 	snd_pcm_hw_params_alloca(&params);
 
@@ -337,12 +342,24 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 		return false;
 
 	ret = snd_pcm_hw_params_test_rate(handle, params, sampling_rate, 0);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_rate_min(params, &min_rate, &min_rate_dir);
+		snd_pcm_hw_params_get_rate_max(params, &max_rate, &max_rate_dir);
+		igt_debug("Output device supports rates between %u and %u, "
+			  "requested %d\n",
+			  min_rate, max_rate, sampling_rate);
 		return false;
+	}
 
 	ret = snd_pcm_hw_params_test_channels(handle, params, channels);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_channels_min(params, &min_channels);
+		snd_pcm_hw_params_get_channels_max(params, &max_channels);
+		igt_debug("Output device supports between %u and "
+			  "%u channels, requested %d\n",
+			  min_channels, max_channels, channels);
 		return false;
+	}
 
 	return true;
 }
@@ -409,13 +426,16 @@ void alsa_configure_output(struct alsa *alsa, int channels,
 	snd_pcm_t *handle;
 	int ret;
 	int i;
+	int soft_resample = 0; /* Don't allow ALSA to resample */
+	unsigned int latency = 0;
 
 	for (i = 0; i < alsa->output_handles_count; i++) {
 		handle = alsa->output_handles[i];
 
 		ret = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE,
 					 SND_PCM_ACCESS_RW_INTERLEAVED,
-					 channels, sampling_rate, 0, 0);
+					 channels, sampling_rate,
+					 soft_resample, latency);
 		igt_assert(ret >= 0);
 	}
 
lib/igt_audio.c +72 -47

240 lines not on this page · raw message

lib/igt_audio.h +7 -4
index 4aa43e69..fe26bb57 100644
@@ -35,12 +35,15 @@
 struct audio_signal;
 
 struct audio_signal *audio_signal_init(int channels, int sampling_rate);
-int audio_signal_add_frequency(struct audio_signal *signal, int frequency);
+void audio_signal_deinit(struct audio_signal *signal);
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
+			       int channel);
 void audio_signal_synthesize(struct audio_signal *signal);
-void audio_signal_clean(struct audio_signal *signal);
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames);
+void audio_signal_reset(struct audio_signal *signal);
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
+		       size_t buffer_len);
 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
-			 double *data, size_t data_len);
+			 int channel, double *data, size_t data_len);
 size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
 				    int32_t *src, size_t src_len,
 				    int n_channels, int channel);
tests/kms_chamelium.c +35 -21

112 lines not on this page · raw message

Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Reviewed-by on v6 3/7
#5 lore raw

Re: [igt-dev] [PATCH i-g-t v6 3/7] tests/kms_chamelium: test we receive a signal from both audio channels

Quoted 25 lines · Simon Ser

This commit updates the audio test to make sure we receive a signal from both audio channels. However this commit doesn't check that left and right channels are not swapped. Such a check requires some more work (because the Chamelium device does swap left and right channels) and will be implemented in a future commit.

This commit adds a new channel argument to audio_signal_add_frequency, to add a frequency to a single channel only.

Some light refactoring has been performed (a proper audio_signal_deinit function has been introduced) and logging has been improved.

---
 lib/igt_alsa.c        |  26 +++++++--
 lib/igt_audio.c       | 119 +++++++++++++++++++++++++-----------------
 lib/igt_audio.h       |  11 ++--
 tests/kms_chamelium.c |  56 ++++++++++++--------
 4 files changed, 137 insertions(+), 75 deletions(-)
lib/igt_alsa.c +0 -0
index fc6d336b..a478686a 100644

lib/igt_alsa.c static char *alsa_resolve_indentifier(const char *device_name, int skip) · line 186

Quoted 5 lines
lib/igt_alsa.c +2 -0
@@ -182,6 +182,8 @@ static char *alsa_resolve_indentifier(const char *device_name, int skip)
 					continue;
 				}
 
+				igt_debug("Matched device \"%s\"\n", pcm_name);
+

Should have been a separate commit.

Quoted 16 lines
lib/igt_alsa.c +3 -0
 				snprintf(name, sizeof(name), "hw:%d,%d", card,
 					 dev);
 
@@ -329,6 +331,9 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 {
 	snd_pcm_hw_params_t *params;
 	int ret;
+	unsigned int min_channels, max_channels;
+	unsigned int min_rate, max_rate;
+	int min_rate_dir, max_rate_dir;
 
 	snd_pcm_hw_params_alloca(&params);
 
@@ -337,12 +342,24 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 		return false;
 

lib/igt_alsa.c static bool alsa_test_configuration(snd_pcm_t *handle, int channels, · line 352

Quoted 10 lines
lib/igt_alsa.c +7 -1
 	ret = snd_pcm_hw_params_test_rate(handle, params, sampling_rate, 0);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_rate_min(params, &min_rate, &min_rate_dir);
+		snd_pcm_hw_params_get_rate_max(params, &max_rate, &max_rate_dir);
+		igt_debug("Output device supports rates between %u and %u, "
+			  "requested %d\n",
+			  min_rate, max_rate, sampling_rate);
 		return false;
+	}

This likely should be in patch 5/7.

Quoted 19 lines
lib/igt_alsa.c +8 -1
 	ret = snd_pcm_hw_params_test_channels(handle, params, channels);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_channels_min(params, &min_channels);
+		snd_pcm_hw_params_get_channels_max(params, &max_channels);
+		igt_debug("Output device supports between %u and "
+			  "%u channels, requested %d\n",
+			  min_channels, max_channels, channels);
 		return false;
+	}
 
 	return true;
 }
@@ -409,13 +426,16 @@ void alsa_configure_output(struct alsa *alsa, int channels,
 	snd_pcm_t *handle;
 	int ret;
 	int i;
+	int soft_resample = 0; /* Don't allow ALSA to resample */

lib/igt_alsa.c void alsa_configure_output(struct alsa *alsa, int channels, · line 438

Quoted 10 lines
lib/igt_alsa.c +3 -1
+	unsigned int latency = 0;
 
 	for (i = 0; i < alsa->output_handles_count; i++) {
 		handle = alsa->output_handles[i];
 
 		ret = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE,
 					 SND_PCM_ACCESS_RW_INTERLEAVED,
-					 channels, sampling_rate, 0, 0);
+					 channels, sampling_rate,
+					 soft_resample, latency);

Probably should have been a separate commit again ;)

Quoted 42 lines
lib/igt_alsa.c +0 -0
 		igt_assert(ret >= 0);
 	}
 
lib/igt_audio.c +5 -4
index 7624f565..a2a5c594 100644
@@ -35,7 +35,7 @@
 #include "igt_audio.h"
 #include "igt_core.h"
 
-#define FREQS_MAX	8
+#define FREQS_MAX 64
 
 /**
  * SECTION:igt_audio
@@ -49,9 +49,10 @@
 
 struct audio_signal_freq {
 	int freq;
+	int channel;
 
-	short *period;
-	int frames;
+	int16_t *period;
+	size_t period_len;
 	int offset;
 };
 
@@ -60,7 +61,7 @@ struct audio_signal {
 	int sampling_rate;
 
 	struct audio_signal_freq freqs[FREQS_MAX];
-	int freqs_count;
+	size_t freqs_count;
 };
 
 /**
@@ -89,21 +90,28 @@ struct audio_signal *audio_signal_init(int channels, int sampling_rate)
  * audio_signal_add_frequency:
  * @signal: The target signal structure
  * @frequency: The frequency to add to the signal

lib/igt_audio.c struct audio_signal *audio_signal_init(int channels, int sampling_rate) · line 101

Quoted 10 lines
lib/igt_audio.c +4 -1
+ * @channel: The channel to add this frequency to, or -1 to add it to all
+ * channels
  *
  * Add a frequency to the signal.
  *
  * Returns: An integer equal to zero for success and negative for failure
  */
-int audio_signal_add_frequency(struct audio_signal *signal, int frequency)
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
+			       int channel)

Is the alignment correct here? Doesn't look like it!

Quoted 7 lines
lib/igt_audio.c +2 -3
 {
-	int index = signal->freqs_count;
+	size_t index = signal->freqs_count;
+	struct audio_signal_freq *freq;
 
-	if (index == FREQS_MAX)
-		return -1;

lib/igt_audio.c struct audio_signal *audio_signal_init(int channels, int sampling_rate) · line 114

Quoted 10 lines
lib/igt_audio.c +6 -1
+	igt_assert(index < FREQS_MAX);
+	igt_assert(channel < signal->channels);
 
 	/* Stay within the Nyquist–Shannon sampling theorem. */
-	if (frequency > signal->sampling_rate / 2)
+	if (frequency > signal->sampling_rate / 2) {
+		igt_debug("Skipping frequency %d: too high for a %d Hz "
+			  "sampling rate\n", frequency, signal->sampling_rate);
 		return -1;
+	}

Should have been a separate commit.

Quoted 53 lines
lib/igt_audio.c +12 -12
 	/* Clip the frequency to an integer multiple of the sampling rate.
 	 * This to be able to store a full period of it and use that for
@@ -111,11 +119,14 @@ int audio_signal_add_frequency(struct audio_signal *signal, int frequency)
 	 */
 	frequency = signal->sampling_rate / (signal->sampling_rate / frequency);
 
-	igt_debug("Adding test frequency %d\n", frequency);
+	igt_debug("Adding test frequency %d to channel %d\n",
+		  frequency, channel);
+
+	freq = &signal->freqs[index];
+	memset(freq, 0, sizeof(*freq));
+	freq->freq = frequency;
+	freq->channel = channel;
 
-	signal->freqs[index].freq = frequency;
-	signal->freqs[index].frames = 0;
-	signal->freqs[index].offset = 0;
 	signal->freqs_count++;
 
 	return 0;
@@ -133,20 +144,17 @@ void audio_signal_synthesize(struct audio_signal *signal)
 {
 	int16_t *period;
 	double value;
-	int frames;
+	size_t period_len;
 	int freq;
 	int i, j;
 
-	if (signal->freqs_count == 0)
-		return;
-
 	for (i = 0; i < signal->freqs_count; i++) {
 		freq = signal->freqs[i].freq;
-		frames = signal->sampling_rate / freq;
+		period_len = signal->sampling_rate / freq;
 
-		period = calloc(1, frames * sizeof(short));
+		period = calloc(1, period_len * sizeof(int16_t));
 
-		for (j = 0; j < frames; j++) {
+		for (j = 0; j < period_len; j++) {
 			value = 2.0 * M_PI * freq / signal->sampling_rate * j;
 			value = sin(value) * INT16_MAX / signal->freqs_count;
 
@@ -154,26 +162,34 @@ void audio_signal_synthesize(struct audio_signal *signal)
 		}
 
 		signal->freqs[i].period = period;
-		signal->freqs[i].frames = frames;
+		signal->freqs[i].period_len = period_len;

lib/igt_audio.c void audio_signal_synthesize(struct audio_signal *signal) · line 174

Quoted 10 lines
lib/igt_audio.c +5 -1
 	}
 }
 
 /**
- * audio_signal_synthesize:
+ * audio_signal_deinit:
+ *
+ * Release the signal.
+ */
+void audio_signal_deinit(struct audio_signal *signal)

Is the coding style to use deinit or fini?

Quoted 262 lines
lib/igt_audio.c +38 -25
+{
+	audio_signal_reset(signal);
+	free(signal);
+}
+
+/**
+ * audio_signal_reset:
  * @signal: The target signal structure
  *
  * Free the resources allocated by audio_signal_synthesize and remove
  * the previously-added frequencies.
  */
-void audio_signal_clean(struct audio_signal *signal)
+void audio_signal_reset(struct audio_signal *signal)
 {
-	int i;
+	size_t i;
 
 	for (i = 0; i < signal->freqs_count; i++) {
-		if (signal->freqs[i].period)
-			free(signal->freqs[i].period);
-
-		memset(&signal->freqs[i], 0, sizeof(struct audio_signal_freq));
+		free(signal->freqs[i].period);
 	}
 
 	signal->freqs_count = 0;
@@ -183,44 +199,45 @@ void audio_signal_clean(struct audio_signal *signal)
  * audio_signal_fill:
  * @signal: The target signal structure
  * @buffer: The target buffer to fill
- * @frames: The number of frames to fill
+ * @samples: The number of samples to fill
  *
- * Fill the requested number of frames to the target buffer with the audio
+ * Fill the requested number of samples to the target buffer with the audio
  * signal data (in interleaved S16_LE format), at the requested sampling rate
  * and number of channels.
  */
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames)
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
+		       size_t buffer_len)
 {
 	int16_t *destination, *source;
+	struct audio_signal_freq *freq;
 	int total;
-	int freq_frames;
-	int freq_offset;
 	int count;
 	int i, j, k;
 
-	memset(buffer, 0, sizeof(int16_t) * signal->channels * frames);
+	memset(buffer, 0, sizeof(int16_t) * signal->channels * buffer_len);
 
 	for (i = 0; i < signal->freqs_count; i++) {
+		freq = &signal->freqs[i];
 		total = 0;
 
-		while (total < frames) {
-			freq_frames = signal->freqs[i].frames;
-			freq_offset = signal->freqs[i].offset;
+		igt_assert(freq->period);
 
-			source = signal->freqs[i].period + freq_offset;
+		while (total < buffer_len) {
+			source = freq->period + freq->offset;
 			destination = buffer + total * signal->channels;
 
-			count = freq_frames - freq_offset;
-			if (count > (frames - total))
-				count = frames - total;
+			count = freq->period_len - freq->offset;
+			if (count > buffer_len - total)
+				count = buffer_len - total;
 
-			freq_offset += count;
-			freq_offset %= freq_frames;
-
-			signal->freqs[i].offset = freq_offset;
+			freq->offset += count;
+			freq->offset %= freq->period_len;
 
 			for (j = 0; j < count; j++) {
 				for (k = 0; k < signal->channels; k++) {
+					if (freq->channel >= 0 &&
+					    freq->channel != k)
+						continue;
 					destination[j * signal->channels + k] += source[j];
 				}
 			}
@@ -237,11 +254,11 @@ void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames)
  * sampling_rate is given in Hz. data_len is the number of elements in data.
  */
 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
-			 double *data, size_t data_len)
+			 int channel, double *data, size_t data_len)
 {
 	size_t bin_power_len = data_len / 2 + 1;
 	double bin_power[bin_power_len];
-	bool detected[signal->freqs_count];
+	bool detected[FREQS_MAX];
 	int ret, freq_accuracy, freq, local_max_freq;
 	double max, local_max, threshold;
 	size_t i, j;
@@ -308,6 +325,10 @@ bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
 		 * invalid. */
 		if (bin_power[i] < threshold) {
 			for (j = 0; j < signal->freqs_count; j++) {
+				if (signal->freqs[j].channel >= 0 &&
+				    signal->freqs[j].channel != channel)
+					continue;
+
 				if (signal->freqs[j].freq >
 				    local_max_freq - freq_accuracy &&
 				    signal->freqs[j].freq <
@@ -340,6 +361,10 @@ bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
 
 	/* Check that all frequencies we generated have been detected. */
 	for (i = 0; i < signal->freqs_count; i++) {
+		if (signal->freqs[i].channel >= 0 &&
+		    signal->freqs[i].channel != channel)
+			continue;
+
 		if (!detected[i]) {
 			igt_debug("Missing frequency: %d\n",
 				  signal->freqs[i].freq);
lib/igt_audio.h +7 -4
index 4aa43e69..fe26bb57 100644
@@ -35,12 +35,15 @@
 struct audio_signal;
 
 struct audio_signal *audio_signal_init(int channels, int sampling_rate);
-int audio_signal_add_frequency(struct audio_signal *signal, int frequency);
+void audio_signal_deinit(struct audio_signal *signal);
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
+			       int channel);
 void audio_signal_synthesize(struct audio_signal *signal);
-void audio_signal_clean(struct audio_signal *signal);
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames);
+void audio_signal_reset(struct audio_signal *signal);
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
+		       size_t buffer_len);
 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
-			 double *data, size_t data_len);
+			 int channel, double *data, size_t data_len);
 size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
 				    int32_t *src, size_t src_len,
 				    int n_channels, int channel);
tests/kms_chamelium.c +33 -18
index 014a22b3..d336612f 100644
@@ -777,16 +777,16 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		      struct alsa *alsa, int playback_channels,
 		      int playback_rate)
 {
-	int ret, capture_rate, capture_channels, msec;
+	int ret, capture_rate, capture_channels, msec, freq;
 	struct chamelium_audio_file *audio_file;
 	struct chamelium_stream *stream;
 	enum chamelium_stream_realtime_mode stream_mode;
 	struct audio_signal *signal;
 	int32_t *recv, *buf;
 	double *channel;
-	size_t i, streak, page_count;
+	size_t i, j, streak, page_count;
 	size_t recv_len, buf_len, buf_cap, buf_size, channel_len;
-	bool ok;
+	bool ok, success;
 	char dump_suffix[64];
 	char *dump_path = NULL;
 	int dump_fd = -1;
@@ -794,10 +794,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	struct audio_state state = {};
 
 	if (!alsa_test_output_configuration(alsa, playback_channels,
-					    playback_rate))
+					    playback_rate)) {
+		igt_debug("Skipping test with sample rate %d and %d channels "
+			  "because selected output devices don't support this "
+			  "configuration\n", playback_rate, playback_channels);
 		return false;
+	}
 
-	igt_debug("Testing with playback sampling rate %d\n", playback_rate);
+	igt_debug("Testing with playback sampling rate %d and %d channels\n",
+		  playback_rate, playback_channels);
 	alsa_configure_output(alsa, playback_channels, playback_rate);
 
 	chamelium_start_capturing_audio(data->chamelium, port, false);
@@ -825,8 +830,12 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
-	for (i = 0; i < test_frequencies_count; i++)
-		audio_signal_add_frequency(signal, test_frequencies[i]);
+	for (i = 0; i < test_frequencies_count; i++) {
+		for (j = 0; j < playback_channels; j++) {
+			freq = test_frequencies[i];
+			audio_signal_add_frequency(signal, freq, j);
+		}
+	}
 	audio_signal_synthesize(signal);
 
 	state.signal = signal;
@@ -851,10 +860,11 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	recv = NULL;
 	recv_len = 0;
 
+	success = false;
 	streak = 0;
 	msec = 0;
 	i = 0;
-	while (streak < MIN_STREAK && msec < AUDIO_TIMEOUT) {
+	while (!success && msec < AUDIO_TIMEOUT) {
 		ok = chamelium_stream_receive_realtime_audio(stream,
 							     &page_count,
 							     &recv, &recv_len);
@@ -872,21 +882,27 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 			igt_assert(write(dump_fd, buf, buf_size) == buf_size);
 		}
 
-		/* TODO: check other channels too, not just the first one */
-		audio_extract_channel_s32_le(channel, channel_len, buf, buf_len,
-					     capture_channels, 0);
-
 		msec = i * channel_len / (double) capture_rate * 1000;
 		igt_debug("Detecting audio signal, t=%d msec\n", msec);
 
-		if (audio_signal_detect(signal, capture_rate, channel,
-					channel_len))
-			streak++;
-		else
-			streak = 0;
+		for (j = 0; j < playback_channels; j++) {
+			igt_debug("Processing channel %zu\n", j);
+
+			audio_extract_channel_s32_le(channel, channel_len,
+						     buf, buf_len,
+						     capture_channels, j);
+
+			if (audio_signal_detect(signal, capture_rate, j,
+						channel, channel_len))
+				streak++;
+			else
+				streak = 0;
+		}
 
 		buf_len = 0;
 		i++;
+
+		success = streak == MIN_STREAK * playback_channels;
 	}
 
 	igt_debug("Stopping audio playback\n");
@@ -921,12 +937,10 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		chamelium_destroy_audio_file(audio_file);
 	}
 
-	audio_signal_clean(signal);

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 946

Quoted 10 lines
tests/kms_chamelium.c +2 -3
-	free(signal);
-
+	audio_signal_deinit(signal);
 	chamelium_stream_deinit(stream);
 
-	igt_assert(streak == MIN_STREAK);
+	igt_assert(success);
 	return true;
 }
 

With the coding style issues fixed:

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#6 lore raw

Re: [igt-dev] [PATCH i-g-t v6 3/7] tests/kms_chamelium: test we receive a signal from both audio channels

Quoted 29 lines · Martin Peres
Quoted 28 lines · Simon Ser

This commit updates the audio test to make sure we receive a signal from both audio channels. However this commit doesn't check that left and right channels are not swapped. Such a check requires some more work (because the Chamelium device does swap left and right channels) and will be implemented in a future commit.

This commit adds a new channel argument to audio_signal_add_frequency, to add a frequency to a single channel only.

Some light refactoring has been performed (a proper audio_signal_deinit function has been introduced) and logging has been improved.

---
 lib/igt_alsa.c        |  26 +++++++--
 lib/igt_audio.c       | 119 +++++++++++++++++++++++++-----------------
 lib/igt_audio.h       |  11 ++--
 tests/kms_chamelium.c |  56 ++++++++++++--------
 4 files changed, 137 insertions(+), 75 deletions(-)
lib/igt_alsa.c +0 -0
index fc6d336b..a478686a 100644
@@ -182,6 +182,8 @@ static char *alsa_resolve_indentifier(const char *device_name, int skip)
 					continue;
 				}
 
Quoted 4 lines

lib/igt_alsa.c static char *alsa_resolve_indentifier(const char *device_name, int skip) · line 186

Quoted 2 lines
lib/igt_alsa.c +2 -0
+				igt_debug("Matched device \"%s\"\n", pcm_name);
+

Should have been a separate commit.

Split into a separate commit.

Quoted 16 lines
Quoted 16 lines
lib/igt_alsa.c +3 -0
 				snprintf(name, sizeof(name), "hw:%d,%d", card,
 					 dev);
 
@@ -329,6 +331,9 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 {
 	snd_pcm_hw_params_t *params;
 	int ret;
+	unsigned int min_channels, max_channels;
+	unsigned int min_rate, max_rate;
+	int min_rate_dir, max_rate_dir;
 
 	snd_pcm_hw_params_alloca(&params);
 
@@ -337,12 +342,24 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 		return false;
 
Quoted 12 lines

lib/igt_alsa.c static bool alsa_test_configuration(snd_pcm_t *handle, int channels, · line 352

Quoted 10 lines
lib/igt_alsa.c +7 -1
 	ret = snd_pcm_hw_params_test_rate(handle, params, sampling_rate, 0);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_rate_min(params, &min_rate, &min_rate_dir);
+		snd_pcm_hw_params_get_rate_max(params, &max_rate, &max_rate_dir);
+		igt_debug("Output device supports rates between %u and %u, "
+			  "requested %d\n",
+			  min_rate, max_rate, sampling_rate);
 		return false;
+	}

This likely should be in patch 5/7.

Split into a separate commit instead (with other logging-related changes).

Quoted 24 lines
Quoted 24 lines
lib/igt_alsa.c +9 -1
 	ret = snd_pcm_hw_params_test_channels(handle, params, channels);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_channels_min(params, &min_channels);
+		snd_pcm_hw_params_get_channels_max(params, &max_channels);
+		igt_debug("Output device supports between %u and "
+			  "%u channels, requested %d\n",
+			  min_channels, max_channels, channels);
 		return false;
+	}
 
 	return true;
 }
@@ -409,13 +426,16 @@ void alsa_configure_output(struct alsa *alsa, int channels,
 	snd_pcm_t *handle;
 	int ret;
 	int i;
+	int soft_resample = 0; /* Don't allow ALSA to resample */
+	unsigned int latency = 0;
 
 	for (i = 0; i < alsa->output_handles_count; i++) {
 		handle = alsa->output_handles[i];
 
Quoted 7 lines

lib/igt_alsa.c void alsa_configure_output(struct alsa *alsa, int channels, · line 438

Quoted 5 lines
lib/igt_alsa.c +2 -1
 		ret = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE,
 					 SND_PCM_ACCESS_RW_INTERLEAVED,
-					 channels, sampling_rate, 0, 0);
+					 channels, sampling_rate,
+					 soft_resample, latency);

Probably should have been a separate commit again ;)

Split into a separate commit.

Quoted 46 lines
Quoted 46 lines
lib/igt_alsa.c +0 -0
 		igt_assert(ret >= 0);
 	}
 
lib/igt_audio.c +7 -4
index 7624f565..a2a5c594 100644
@@ -35,7 +35,7 @@
 #include "igt_audio.h"
 #include "igt_core.h"
 
-#define FREQS_MAX	8
+#define FREQS_MAX 64
 
 /**
  * SECTION:igt_audio
@@ -49,9 +49,10 @@
 
 struct audio_signal_freq {
 	int freq;
+	int channel;
 
-	short *period;
-	int frames;
+	int16_t *period;
+	size_t period_len;
 	int offset;
 };
 
@@ -60,7 +61,7 @@ struct audio_signal {
 	int sampling_rate;
 
 	struct audio_signal_freq freqs[FREQS_MAX];
-	int freqs_count;
+	size_t freqs_count;
 };
 
 /**
@@ -89,21 +90,28 @@ struct audio_signal *audio_signal_init(int channels, int sampling_rate)
  * audio_signal_add_frequency:
  * @signal: The target signal structure
  * @frequency: The frequency to add to the signal
+ * @channel: The channel to add this frequency to, or -1 to add it to all
+ * channels
  *
  * Add a frequency to the signal.
Quoted 8 lines

lib/igt_audio.c struct audio_signal *audio_signal_init(int channels, int sampling_rate) · line 101

Quoted 6 lines
lib/igt_audio.c +2 -1
  *
  * Returns: An integer equal to zero for success and negative for failure
  */
-int audio_signal_add_frequency(struct audio_signal *signal, int frequency)
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
+			       int channel)

Is the alignment correct here? Doesn't look like it!

Not sure what's going on with vim. It looks fine in vim, but looks bad in git. Let's trust git.

Quoted 10 lines
Quoted 10 lines
lib/igt_audio.c +4 -3
 {
-	int index = signal->freqs_count;
+	size_t index = signal->freqs_count;
+	struct audio_signal_freq *freq;
 
-	if (index == FREQS_MAX)
-		return -1;
+	igt_assert(index < FREQS_MAX);
+	igt_assert(channel < signal->channels);
 
Quoted 9 lines

lib/igt_audio.c struct audio_signal *audio_signal_init(int channels, int sampling_rate) · line 114

Quoted 7 lines
lib/igt_audio.c +4 -1
 	/* Stay within the Nyquist–Shannon sampling theorem. */
-	if (frequency > signal->sampling_rate / 2)
+	if (frequency > signal->sampling_rate / 2) {
+		igt_debug("Skipping frequency %d: too high for a %d Hz "
+			  "sampling rate\n", frequency, signal->sampling_rate);
 		return -1;
+	}

Should have been a separate commit.

Split into a separate commit (along with other logging-related changes).

Quoted 56 lines
Quoted 56 lines
lib/igt_audio.c +12 -12
 	/* Clip the frequency to an integer multiple of the sampling rate.
 	 * This to be able to store a full period of it and use that for
@@ -111,11 +119,14 @@ int audio_signal_add_frequency(struct audio_signal *signal, int frequency)
 	 */
 	frequency = signal->sampling_rate / (signal->sampling_rate / frequency);
 
-	igt_debug("Adding test frequency %d\n", frequency);
+	igt_debug("Adding test frequency %d to channel %d\n",
+		  frequency, channel);
+
+	freq = &signal->freqs[index];
+	memset(freq, 0, sizeof(*freq));
+	freq->freq = frequency;
+	freq->channel = channel;
 
-	signal->freqs[index].freq = frequency;
-	signal->freqs[index].frames = 0;
-	signal->freqs[index].offset = 0;
 	signal->freqs_count++;
 
 	return 0;
@@ -133,20 +144,17 @@ void audio_signal_synthesize(struct audio_signal *signal)
 {
 	int16_t *period;
 	double value;
-	int frames;
+	size_t period_len;
 	int freq;
 	int i, j;
 
-	if (signal->freqs_count == 0)
-		return;
-
 	for (i = 0; i < signal->freqs_count; i++) {
 		freq = signal->freqs[i].freq;
-		frames = signal->sampling_rate / freq;
+		period_len = signal->sampling_rate / freq;
 
-		period = calloc(1, frames * sizeof(short));
+		period = calloc(1, period_len * sizeof(int16_t));
 
-		for (j = 0; j < frames; j++) {
+		for (j = 0; j < period_len; j++) {
 			value = 2.0 * M_PI * freq / signal->sampling_rate * j;
 			value = sin(value) * INT16_MAX / signal->freqs_count;
 
@@ -154,26 +162,34 @@ void audio_signal_synthesize(struct audio_signal *signal)
 		}
 
 		signal->freqs[i].period = period;
-		signal->freqs[i].frames = frames;
+		signal->freqs[i].period_len = period_len;
 	}
 }
 
Quoted 9 lines

lib/igt_audio.c void audio_signal_synthesize(struct audio_signal *signal) · line 174

Quoted 7 lines
lib/igt_audio.c +5 -1
 /**
- * audio_signal_synthesize:
+ * audio_signal_deinit:
+ *
+ * Release the signal.
+ */
+void audio_signal_deinit(struct audio_signal *signal)

Is the coding style to use deinit or fini?

I've used deinit as the code I've seen (igt_alsa, igt_chamelium) uses it. grep says _fini is used a lot more often though, so let's switch to that convention.

Quoted 275 lines
Quoted 262 lines
lib/igt_audio.c +38 -25
+{
+	audio_signal_reset(signal);
+	free(signal);
+}
+
+/**
+ * audio_signal_reset:
  * @signal: The target signal structure
  *
  * Free the resources allocated by audio_signal_synthesize and remove
  * the previously-added frequencies.
  */
-void audio_signal_clean(struct audio_signal *signal)
+void audio_signal_reset(struct audio_signal *signal)
 {
-	int i;
+	size_t i;
 
 	for (i = 0; i < signal->freqs_count; i++) {
-		if (signal->freqs[i].period)
-			free(signal->freqs[i].period);
-
-		memset(&signal->freqs[i], 0, sizeof(struct audio_signal_freq));
+		free(signal->freqs[i].period);
 	}
 
 	signal->freqs_count = 0;
@@ -183,44 +199,45 @@ void audio_signal_clean(struct audio_signal *signal)
  * audio_signal_fill:
  * @signal: The target signal structure
  * @buffer: The target buffer to fill
- * @frames: The number of frames to fill
+ * @samples: The number of samples to fill
  *
- * Fill the requested number of frames to the target buffer with the audio
+ * Fill the requested number of samples to the target buffer with the audio
  * signal data (in interleaved S16_LE format), at the requested sampling rate
  * and number of channels.
  */
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames)
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
+		       size_t buffer_len)
 {
 	int16_t *destination, *source;
+	struct audio_signal_freq *freq;
 	int total;
-	int freq_frames;
-	int freq_offset;
 	int count;
 	int i, j, k;
 
-	memset(buffer, 0, sizeof(int16_t) * signal->channels * frames);
+	memset(buffer, 0, sizeof(int16_t) * signal->channels * buffer_len);
 
 	for (i = 0; i < signal->freqs_count; i++) {
+		freq = &signal->freqs[i];
 		total = 0;
 
-		while (total < frames) {
-			freq_frames = signal->freqs[i].frames;
-			freq_offset = signal->freqs[i].offset;
+		igt_assert(freq->period);
 
-			source = signal->freqs[i].period + freq_offset;
+		while (total < buffer_len) {
+			source = freq->period + freq->offset;
 			destination = buffer + total * signal->channels;
 
-			count = freq_frames - freq_offset;
-			if (count > (frames - total))
-				count = frames - total;
+			count = freq->period_len - freq->offset;
+			if (count > buffer_len - total)
+				count = buffer_len - total;
 
-			freq_offset += count;
-			freq_offset %= freq_frames;
-
-			signal->freqs[i].offset = freq_offset;
+			freq->offset += count;
+			freq->offset %= freq->period_len;
 
 			for (j = 0; j < count; j++) {
 				for (k = 0; k < signal->channels; k++) {
+					if (freq->channel >= 0 &&
+					    freq->channel != k)
+						continue;
 					destination[j * signal->channels + k] += source[j];
 				}
 			}
@@ -237,11 +254,11 @@ void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames)
  * sampling_rate is given in Hz. data_len is the number of elements in data.
  */
 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
-			 double *data, size_t data_len)
+			 int channel, double *data, size_t data_len)
 {
 	size_t bin_power_len = data_len / 2 + 1;
 	double bin_power[bin_power_len];
-	bool detected[signal->freqs_count];
+	bool detected[FREQS_MAX];
 	int ret, freq_accuracy, freq, local_max_freq;
 	double max, local_max, threshold;
 	size_t i, j;
@@ -308,6 +325,10 @@ bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
 		 * invalid. */
 		if (bin_power[i] < threshold) {
 			for (j = 0; j < signal->freqs_count; j++) {
+				if (signal->freqs[j].channel >= 0 &&
+				    signal->freqs[j].channel != channel)
+					continue;
+
 				if (signal->freqs[j].freq >
 				    local_max_freq - freq_accuracy &&
 				    signal->freqs[j].freq <
@@ -340,6 +361,10 @@ bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
 
 	/* Check that all frequencies we generated have been detected. */
 	for (i = 0; i < signal->freqs_count; i++) {
+		if (signal->freqs[i].channel >= 0 &&
+		    signal->freqs[i].channel != channel)
+			continue;
+
 		if (!detected[i]) {
 			igt_debug("Missing frequency: %d\n",
 				  signal->freqs[i].freq);
lib/igt_audio.h +7 -4
index 4aa43e69..fe26bb57 100644
@@ -35,12 +35,15 @@
 struct audio_signal;
 
 struct audio_signal *audio_signal_init(int channels, int sampling_rate);
-int audio_signal_add_frequency(struct audio_signal *signal, int frequency);
+void audio_signal_deinit(struct audio_signal *signal);
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
+			       int channel);
 void audio_signal_synthesize(struct audio_signal *signal);
-void audio_signal_clean(struct audio_signal *signal);
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames);
+void audio_signal_reset(struct audio_signal *signal);
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
+		       size_t buffer_len);
 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
-			 double *data, size_t data_len);
+			 int channel, double *data, size_t data_len);
 size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
 				    int32_t *src, size_t src_len,
 				    int n_channels, int channel);
tests/kms_chamelium.c +33 -18
index 014a22b3..d336612f 100644
@@ -777,16 +777,16 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		      struct alsa *alsa, int playback_channels,
 		      int playback_rate)
 {
-	int ret, capture_rate, capture_channels, msec;
+	int ret, capture_rate, capture_channels, msec, freq;
 	struct chamelium_audio_file *audio_file;
 	struct chamelium_stream *stream;
 	enum chamelium_stream_realtime_mode stream_mode;
 	struct audio_signal *signal;
 	int32_t *recv, *buf;
 	double *channel;
-	size_t i, streak, page_count;
+	size_t i, j, streak, page_count;
 	size_t recv_len, buf_len, buf_cap, buf_size, channel_len;
-	bool ok;
+	bool ok, success;
 	char dump_suffix[64];
 	char *dump_path = NULL;
 	int dump_fd = -1;
@@ -794,10 +794,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	struct audio_state state = {};
 
 	if (!alsa_test_output_configuration(alsa, playback_channels,
-					    playback_rate))
+					    playback_rate)) {
+		igt_debug("Skipping test with sample rate %d and %d channels "
+			  "because selected output devices don't support this "
+			  "configuration\n", playback_rate, playback_channels);
 		return false;
+	}
 
-	igt_debug("Testing with playback sampling rate %d\n", playback_rate);
+	igt_debug("Testing with playback sampling rate %d and %d channels\n",
+		  playback_rate, playback_channels);
 	alsa_configure_output(alsa, playback_channels, playback_rate);
 
 	chamelium_start_capturing_audio(data->chamelium, port, false);
@@ -825,8 +830,12 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
-	for (i = 0; i < test_frequencies_count; i++)
-		audio_signal_add_frequency(signal, test_frequencies[i]);
+	for (i = 0; i < test_frequencies_count; i++) {
+		for (j = 0; j < playback_channels; j++) {
+			freq = test_frequencies[i];
+			audio_signal_add_frequency(signal, freq, j);
+		}
+	}
 	audio_signal_synthesize(signal);
 
 	state.signal = signal;
@@ -851,10 +860,11 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	recv = NULL;
 	recv_len = 0;
 
+	success = false;
 	streak = 0;
 	msec = 0;
 	i = 0;
-	while (streak < MIN_STREAK && msec < AUDIO_TIMEOUT) {
+	while (!success && msec < AUDIO_TIMEOUT) {
 		ok = chamelium_stream_receive_realtime_audio(stream,
 							     &page_count,
 							     &recv, &recv_len);
@@ -872,21 +882,27 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 			igt_assert(write(dump_fd, buf, buf_size) == buf_size);
 		}
 
-		/* TODO: check other channels too, not just the first one */
-		audio_extract_channel_s32_le(channel, channel_len, buf, buf_len,
-					     capture_channels, 0);
-
 		msec = i * channel_len / (double) capture_rate * 1000;
 		igt_debug("Detecting audio signal, t=%d msec\n", msec);
 
-		if (audio_signal_detect(signal, capture_rate, channel,
-					channel_len))
-			streak++;
-		else
-			streak = 0;
+		for (j = 0; j < playback_channels; j++) {
+			igt_debug("Processing channel %zu\n", j);
+
+			audio_extract_channel_s32_le(channel, channel_len,
+						     buf, buf_len,
+						     capture_channels, j);
+
+			if (audio_signal_detect(signal, capture_rate, j,
+						channel, channel_len))
+				streak++;
+			else
+				streak = 0;
+		}
 
 		buf_len = 0;
 		i++;
+
+		success = streak == MIN_STREAK * playback_channels;
 	}
 
 	igt_debug("Stopping audio playback\n");
@@ -921,12 +937,10 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		chamelium_destroy_audio_file(audio_file);
 	}
 
-	audio_signal_clean(signal);

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 946

Quoted 10 lines
tests/kms_chamelium.c +2 -3
-	free(signal);
-
+	audio_signal_deinit(signal);
 	chamelium_stream_deinit(stream);
 
-	igt_assert(streak == MIN_STREAK);
+	igt_assert(success);
 	return true;
 }
 

With the coding style issues fixed:

Quoted 1 line

Thanks for the review!
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#7 lore raw

PATCH v6 4/7 tests/kms_chamelium: test audio channels are not mixed up

In reply to Simon Ser

Send a different signal to each channel and make sure captured audio channels are not swapped or mixed up.

The Chamelium device has a bug and already swaps the left and right channels. For this reason, clients need to retrieve the Chamelium channel mapping and accomodate for this. See https://crbug.com/950922 for a discussion about this.

---
 lib/igt_chamelium.c   | 34 ++++++++++++++++++++++++++++++++++
 lib/igt_chamelium.h   |  3 +++
 tests/kms_chamelium.c | 37 +++++++++++++++++++++++++++++++------
 3 files changed, 68 insertions(+), 6 deletions(-)
lib/igt_chamelium.c +34 -0
index 7c9030d1..6ac7b722 100644
@@ -930,6 +930,40 @@ int chamelium_get_captured_frame_count(struct chamelium *chamelium)
 	return ret;
 }
 
+/**
+ * chamelium_get_audio_channel_mapping:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @mapping: will be filled with the channel mapping
+ *
+ * Obtains the channel mapping for an audio port.
+ *
+ * Audio channels are not guaranteed not to be swapped. Users can use the
+ * channel mapping to match an input channel to a capture channel.
+ *
+ * The mapping contains one element per capture channel. Each element indicates
+ * which input channel the capture channel is mapped to. As a special case, -1
+ * means that the channel isn't mapped.
+ */
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8])
+{
+	xmlrpc_value *res, *res_channel;
+	int res_len, i;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioChannelMapping", "(i)",
+			    port->id);
+	res_len = xmlrpc_array_size(&chamelium->env, res);
+	igt_assert(res_len == 8);
+	for (i = 0; i < res_len; i++) {
+		xmlrpc_array_read_item(&chamelium->env, res, i, &res_channel);
+		xmlrpc_read_int(&chamelium->env, res_channel, &mapping[i]);
+		xmlrpc_DECREF(res_channel);
+	}
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_start_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 047f8c5d..728d16ea 100644
@@ -106,6 +106,9 @@ void chamelium_start_capture(struct chamelium *chamelium,
 void chamelium_stop_capture(struct chamelium *chamelium, int frame_count);
 void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 		       int x, int y, int w, int h, int frame_count);
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8]);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
tests/kms_chamelium.c +31 -6
index d336612f..8d6cc092 100644
@@ -777,7 +777,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		      struct alsa *alsa, int playback_channels,
 		      int playback_rate)
 {
-	int ret, capture_rate, capture_channels, msec, freq;
+	int ret, capture_rate, capture_channels, msec, freq, step;
 	struct chamelium_audio_file *audio_file;
 	struct chamelium_stream *stream;
 	enum chamelium_stream_realtime_mode stream_mode;
@@ -792,16 +792,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	int dump_fd = -1;
 	pthread_t thread;
 	struct audio_state state = {};
+	int channel_mapping[8], capture_chan;
 
 	if (!alsa_test_output_configuration(alsa, playback_channels,
 					    playback_rate)) {
-		igt_debug("Skipping test with sample rate %d and %d channels "
+		igt_debug("Skipping test with sample rate %d Hz and %d channels "
 			  "because selected output devices don't support this "
 			  "configuration\n", playback_rate, playback_channels);
 		return false;
 	}
 
-	igt_debug("Testing with playback sampling rate %d and %d channels\n",
+	igt_debug("Testing with playback sampling rate %d Hz and %d channels\n",
 		  playback_rate, playback_channels);
 	alsa_configure_output(alsa, playback_channels, playback_rate);
 
@@ -830,9 +831,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
+	/* We'll choose different frequencies per channel to make sure they are
+	 * independent from each other. To do so, we'll add a different offset
+	 * to the base frequencies for each channel. We need to choose a big
+	 * enough offset so that we're sure to detect mixed up channels.
+	 */
+	step = 2 * capture_rate / CAPTURE_SAMPLES;
 	for (i = 0; i < test_frequencies_count; i++) {
 		for (j = 0; j < playback_channels; j++) {
-			freq = test_frequencies[i];
+			freq = test_frequencies[i] + j * step;
 			audio_signal_add_frequency(signal, freq, j);
 		}
 	}
@@ -847,6 +854,20 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
+	chamelium_get_audio_channel_mapping(data->chamelium, port,
+					    channel_mapping);
+	/* Make sure we can capture all channels we send. */
+	for (i = 0; i < playback_channels; i++) {
+		ok = false;
+		for (j = 0; j < capture_channels; j++) {
+			if (channel_mapping[j] == i) {
+				ok = true;
+				break;
+			}
+		}
+		igt_assert(ok);
+	}
+
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -886,11 +907,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		igt_debug("Detecting audio signal, t=%d msec\n", msec);
 
 		for (j = 0; j < playback_channels; j++) {
-			igt_debug("Processing channel %zu\n", j);
+			capture_chan = channel_mapping[j];
+			igt_assert(capture_chan >= 0);
+			igt_debug("Processing channel %zu (captured as "
+				  "channel %d)\n", j, capture_chan);
 
 			audio_extract_channel_s32_le(channel, channel_len,
 						     buf, buf_len,
-						     capture_channels, j);
+						     capture_channels,
+						     capture_chan);
 
 			if (audio_signal_detect(signal, capture_rate, j,
 						channel, channel_len))
Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Reviewed-by on v6 4/7
#8 lore raw

Re: [igt-dev] [PATCH i-g-t v6 4/7] tests/kms_chamelium: test audio channels are not mixed up

Quoted 87 lines · Simon Ser

Send a different signal to each channel and make sure captured audio channels are not swapped or mixed up.

The Chamelium device has a bug and already swaps the left and right channels. For this reason, clients need to retrieve the Chamelium channel mapping and accomodate for this. See https://crbug.com/950922 for a discussion about this.

---
 lib/igt_chamelium.c   | 34 ++++++++++++++++++++++++++++++++++
 lib/igt_chamelium.h   |  3 +++
 tests/kms_chamelium.c | 37 +++++++++++++++++++++++++++++++------
 3 files changed, 68 insertions(+), 6 deletions(-)
lib/igt_chamelium.c +34 -0
index 7c9030d1..6ac7b722 100644
@@ -930,6 +930,40 @@ int chamelium_get_captured_frame_count(struct chamelium *chamelium)
 	return ret;
 }
 
+/**
+ * chamelium_get_audio_channel_mapping:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @mapping: will be filled with the channel mapping
+ *
+ * Obtains the channel mapping for an audio port.
+ *
+ * Audio channels are not guaranteed not to be swapped. Users can use the
+ * channel mapping to match an input channel to a capture channel.
+ *
+ * The mapping contains one element per capture channel. Each element indicates
+ * which input channel the capture channel is mapped to. As a special case, -1
+ * means that the channel isn't mapped.
+ */
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8])
+{
+	xmlrpc_value *res, *res_channel;
+	int res_len, i;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioChannelMapping", "(i)",
+			    port->id);
+	res_len = xmlrpc_array_size(&chamelium->env, res);
+	igt_assert(res_len == 8);
+	for (i = 0; i < res_len; i++) {
+		xmlrpc_array_read_item(&chamelium->env, res, i, &res_channel);
+		xmlrpc_read_int(&chamelium->env, res_channel, &mapping[i]);
+		xmlrpc_DECREF(res_channel);
+	}
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_start_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 047f8c5d..728d16ea 100644
@@ -106,6 +106,9 @@ void chamelium_start_capture(struct chamelium *chamelium,
 void chamelium_stop_capture(struct chamelium *chamelium, int frame_count);
 void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 		       int x, int y, int w, int h, int frame_count);
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8]);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
tests/kms_chamelium.c +1 -1
index d336612f..8d6cc092 100644
@@ -777,7 +777,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		      struct alsa *alsa, int playback_channels,
 		      int playback_rate)
 {
-	int ret, capture_rate, capture_channels, msec, freq;
+	int ret, capture_rate, capture_channels, msec, freq, step;
 	struct chamelium_audio_file *audio_file;
 	struct chamelium_stream *stream;
 	enum chamelium_stream_realtime_mode stream_mode;

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 800

Quoted 10 lines
tests/kms_chamelium.c +2 -1
@@ -792,16 +792,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	int dump_fd = -1;
 	pthread_t thread;
 	struct audio_state state = {};
+	int channel_mapping[8], capture_chan;
 
 	if (!alsa_test_output_configuration(alsa, playback_channels,
 					    playback_rate)) {
-		igt_debug("Skipping test with sample rate %d and %d channels "
+		igt_debug("Skipping test with sample rate %d Hz and %d channels "
 			  "because selected output devices don't support this "

How about "because at least some output devices do not support this"?

Quoted 10 lines
tests/kms_chamelium.c +1 -1
 			  "configuration\n", playback_rate, playback_channels);
 		return false;
 	}
 
-	igt_debug("Testing with playback sampling rate %d and %d channels\n",
+	igt_debug("Testing with playback sampling rate %d Hz and %d channels\n",
 		  playback_rate, playback_channels);
 	alsa_configure_output(alsa, playback_channels, playback_rate);
 

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 839

Quoted 9 lines
tests/kms_chamelium.c +6 -0
@@ -830,9 +831,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
+	/* We'll choose different frequencies per channel to make sure they are
+	 * independent from each other. To do so, we'll add a different offset
+	 * to the base frequencies for each channel. We need to choose a big
+	 * enough offset so that we're sure to detect mixed up channels.
+	 */
+	step = 2 * capture_rate / CAPTURE_SAMPLES;

Please say that this formula adds an offset of 2 bins in the final FFT, thus enforcing a clear difference (please make sure of that).

Quoted 37 lines
tests/kms_chamelium.c +18 -2
 	for (i = 0; i < test_frequencies_count; i++) {
 		for (j = 0; j < playback_channels; j++) {
-			freq = test_frequencies[i];
+			freq = test_frequencies[i] + j * step;
 			audio_signal_add_frequency(signal, freq, j);
 		}
 	}
@@ -847,6 +854,20 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
+	chamelium_get_audio_channel_mapping(data->chamelium, port,
+					    channel_mapping);
+	/* Make sure we can capture all channels we send. */
+	for (i = 0; i < playback_channels; i++) {
+		ok = false;
+		for (j = 0; j < capture_channels; j++) {
+			if (channel_mapping[j] == i) {
+				ok = true;
+				break;
+			}
+		}
+		igt_assert(ok);
+	}
+
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -886,11 +907,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		igt_debug("Detecting audio signal, t=%d msec\n", msec);
 
 		for (j = 0; j < playback_channels; j++) {
-			igt_debug("Processing channel %zu\n", j);
+			capture_chan = channel_mapping[j];
+			igt_assert(capture_chan >= 0);
+			igt_debug("Processing channel %zu (captured as "

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 921

Quoted 10 lines
tests/kms_chamelium.c +3 -1
+				  "channel %d)\n", j, capture_chan);
 
 			audio_extract_channel_s32_le(channel, channel_len,
 						     buf, buf_len,
-						     capture_channels, j);
+						     capture_channels,
+						     capture_chan);
 
 			if (audio_signal_detect(signal, capture_rate, j,
 						channel, channel_len))

Looks great!

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#9 lore raw

Re: [igt-dev] [PATCH i-g-t v6 4/7] tests/kms_chamelium: test audio channels are not mixed up

Quoted 114 lines · Martin Peres
Quoted 87 lines · Simon Ser

Send a different signal to each channel and make sure captured audio channels are not swapped or mixed up.

The Chamelium device has a bug and already swaps the left and right channels. For this reason, clients need to retrieve the Chamelium channel mapping and accomodate for this. See https://crbug.com/950922 for a discussion about this.

---
 lib/igt_chamelium.c   | 34 ++++++++++++++++++++++++++++++++++
 lib/igt_chamelium.h   |  3 +++
 tests/kms_chamelium.c | 37 +++++++++++++++++++++++++++++++------
 3 files changed, 68 insertions(+), 6 deletions(-)
lib/igt_chamelium.c +34 -0
index 7c9030d1..6ac7b722 100644
@@ -930,6 +930,40 @@ int chamelium_get_captured_frame_count(struct chamelium *chamelium)
 	return ret;
 }
 
+/**
+ * chamelium_get_audio_channel_mapping:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @mapping: will be filled with the channel mapping
+ *
+ * Obtains the channel mapping for an audio port.
+ *
+ * Audio channels are not guaranteed not to be swapped. Users can use the
+ * channel mapping to match an input channel to a capture channel.
+ *
+ * The mapping contains one element per capture channel. Each element indicates
+ * which input channel the capture channel is mapped to. As a special case, -1
+ * means that the channel isn't mapped.
+ */
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8])
+{
+	xmlrpc_value *res, *res_channel;
+	int res_len, i;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioChannelMapping", "(i)",
+			    port->id);
+	res_len = xmlrpc_array_size(&chamelium->env, res);
+	igt_assert(res_len == 8);
+	for (i = 0; i < res_len; i++) {
+		xmlrpc_array_read_item(&chamelium->env, res, i, &res_channel);
+		xmlrpc_read_int(&chamelium->env, res_channel, &mapping[i]);
+		xmlrpc_DECREF(res_channel);
+	}
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_start_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 047f8c5d..728d16ea 100644
@@ -106,6 +106,9 @@ void chamelium_start_capture(struct chamelium *chamelium,
 void chamelium_stop_capture(struct chamelium *chamelium, int frame_count);
 void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 		       int x, int y, int w, int h, int frame_count);
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8]);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
tests/kms_chamelium.c +1 -1
index d336612f..8d6cc092 100644
@@ -777,7 +777,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		      struct alsa *alsa, int playback_channels,
 		      int playback_rate)
 {
-	int ret, capture_rate, capture_channels, msec, freq;
+	int ret, capture_rate, capture_channels, msec, freq, step;
 	struct chamelium_audio_file *audio_file;
 	struct chamelium_stream *stream;
 	enum chamelium_stream_realtime_mode stream_mode;

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 800

Quoted 10 lines
tests/kms_chamelium.c +2 -1
@@ -792,16 +792,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	int dump_fd = -1;
 	pthread_t thread;
 	struct audio_state state = {};
+	int channel_mapping[8], capture_chan;
 
 	if (!alsa_test_output_configuration(alsa, playback_channels,
 					    playback_rate)) {
-		igt_debug("Skipping test with sample rate %d and %d channels "
+		igt_debug("Skipping test with sample rate %d Hz and %d channels "
 			  "because selected output devices don't support this "

How about "because at least some output devices do not support this"?

Quoted 13 lines
tests/kms_chamelium.c +1 -1
 			  "configuration\n", playback_rate, playback_channels);
 		return false;
 	}
 
-	igt_debug("Testing with playback sampling rate %d and %d channels\n",
+	igt_debug("Testing with playback sampling rate %d Hz and %d channels\n",
 		  playback_rate, playback_channels);
 	alsa_configure_output(alsa, playback_channels, playback_rate);
 
@@ -830,9 +831,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
Quoted 9 lines

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 839

Quoted 6 lines
tests/kms_chamelium.c +6 -0
+	/* We'll choose different frequencies per channel to make sure they are
+	 * independent from each other. To do so, we'll add a different offset
+	 * to the base frequencies for each channel. We need to choose a big
+	 * enough offset so that we're sure to detect mixed up channels.
+	 */
+	step = 2 * capture_rate / CAPTURE_SAMPLES;

Please say that this formula adds an offset of 2 bins in the final FFT, thus enforcing a clear difference (please make sure of that).

Indeed, better to be clear about this. Yeah, made sure this is correct, the formula is the same as the one in audio_signal_detect:

    freq = sampling_rate * i / data_len;

i is the bin index, data_len the number of samples.

Quoted 44 lines
Quoted 44 lines
tests/kms_chamelium.c +21 -3
 	for (i = 0; i < test_frequencies_count; i++) {
 		for (j = 0; j < playback_channels; j++) {
-			freq = test_frequencies[i];
+			freq = test_frequencies[i] + j * step;
 			audio_signal_add_frequency(signal, freq, j);
 		}
 	}
@@ -847,6 +854,20 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
+	chamelium_get_audio_channel_mapping(data->chamelium, port,
+					    channel_mapping);
+	/* Make sure we can capture all channels we send. */
+	for (i = 0; i < playback_channels; i++) {
+		ok = false;
+		for (j = 0; j < capture_channels; j++) {
+			if (channel_mapping[j] == i) {
+				ok = true;
+				break;
+			}
+		}
+		igt_assert(ok);
+	}
+
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -886,11 +907,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		igt_debug("Detecting audio signal, t=%d msec\n", msec);
 
 		for (j = 0; j < playback_channels; j++) {
-			igt_debug("Processing channel %zu\n", j);
+			capture_chan = channel_mapping[j];
+			igt_assert(capture_chan >= 0);
+			igt_debug("Processing channel %zu (captured as "
+				  "channel %d)\n", j, capture_chan);
 
 			audio_extract_channel_s32_le(channel, channel_len,
 						     buf, buf_len,
-						     capture_channels, j);
+						     capture_channels,
+						     capture_chan);
 
Quoted 7 lines

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 921

Quoted 3 lines
tests/kms_chamelium.c +0 -0
 			if (audio_signal_detect(signal, capture_rate, j,
 						channel, channel_len))

Looks great!

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#10 lore raw

PATCH v6 5/7 tests/kms_chamelium: run audio test with multiple sampling rates

In reply to Simon Ser

The audio test is now run multiple times with a variety of playback sampling rates.

We now query the capture audio format from the Chamelium XML-RPC API instead of hardcoding it.

One limitation is that we need to start sendting an audio signal before being able to query the capture audio format. However we need the capture sample rate to decide which frequencies we generate. For now we use the playback rate and check that it's the same as the capture rate.

Another limitation is that the DP receiver reports an unknown sampling rate during the 41.1KHz test. In this case we assume the capture rate is the same as the playback rate. We'll fail later anyway if this assumption is incorrect since we check the signal we receive.

Chameleon bug: https://crbug.com/950913

---
 lib/igt_chamelium.c        | 80 +++++++++++++++++++++++++-------------
 lib/igt_chamelium.h        |  3 ++
 lib/igt_chamelium_stream.c | 17 --------
 lib/igt_chamelium_stream.h |  2 -
 tests/kms_chamelium.c      | 56 +++++++++++++++-----------
 5 files changed, 90 insertions(+), 68 deletions(-)
lib/igt_chamelium.c +53 -27
index 6ac7b722..ffc68f35 100644
@@ -964,31 +964,6 @@ void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 	xmlrpc_DECREF(res);
 }
 
-/**
- * chamelium_start_capturing_audio:
- * @chamelium: the Chamelium instance
- * @port: the port to capture audio from (it must support audio)
- * @save_to_file: whether the captured audio data should be saved to a file on
- * the Chamelium device
- *
- * Starts capturing audio from a Chamelium port. To stop the capture, use
- * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
- * stream server or enable @save_to_file (the latter is mainly useful for
- * debugging purposes).
- *
- * It isn't possible to capture audio from multiple ports at the same time.
- */
-void chamelium_start_capturing_audio(struct chamelium *chamelium,
-				    struct chamelium_port *port,
-				    bool save_to_file)
-{
-	xmlrpc_value *res;
-
-	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
-			    port->id, save_to_file);
-	xmlrpc_DECREF(res);
-}
-
 static void audio_format_from_xml(struct chamelium *chamelium,
 				  xmlrpc_value *res, int *rate, int *channels)
 {
@@ -1008,8 +983,10 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	igt_assert(strcmp(sample_format, "S32_LE") == 0);
 	free(sample_format);
 
-	xmlrpc_read_int(&chamelium->env, res_rate, rate);
-	xmlrpc_read_int(&chamelium->env, res_channel, channels);
+	if (rate)
+		xmlrpc_read_int(&chamelium->env, res_rate, rate);
+	if (channels)
+		xmlrpc_read_int(&chamelium->env, res_channel, channels);
 
 	xmlrpc_DECREF(res_channel);
 	xmlrpc_DECREF(res_sample_format);
@@ -1017,6 +994,55 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	xmlrpc_DECREF(res_type);
 }
 
+/**
+ * chamelium_get_audio_format:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @rate: if non-NULL, will be set to the sample rate in Hz
+ * @channels: if non-NULL, will be set to the number of channels
+ *
+ * Obtains the audio format of the captured data. Users should start sending an
+ * audio signal to the Chamelium device prior to calling this function.
+ *
+ * The captured data is guaranteed to be in the S32_LE format.
+ */
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioFormat", "(i)",
+			    port->id);
+	audio_format_from_xml(chamelium, res, rate, channels);
+	xmlrpc_DECREF(res);
+}
+
+/**
+ * chamelium_start_capturing_audio:
+ * @chamelium: the Chamelium instance
+ * @port: the port to capture audio from (it must support audio)
+ * @save_to_file: whether the captured audio data should be saved to a file on
+ * the Chamelium device
+ *
+ * Starts capturing audio from a Chamelium port. To stop the capture, use
+ * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
+ * stream server or enable @save_to_file (the latter is mainly useful for
+ * debugging purposes).
+ *
+ * It isn't possible to capture audio from multiple ports at the same time.
+ */
+void chamelium_start_capturing_audio(struct chamelium *chamelium,
+				    struct chamelium_port *port,
+				    bool save_to_file)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
+			    port->id, save_to_file);
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_stop_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 728d16ea..f47b84cb 100644
@@ -109,6 +109,9 @@ void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 					 struct chamelium_port *port,
 					 int mapping[static 8]);
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
lib/igt_chamelium_stream.c +0 -17
index 68ddb217..a8cd19e5 100644
@@ -537,23 +537,6 @@ bool chamelium_stream_stop_realtime_audio(struct chamelium_stream *client)
 	return true;
 }
 
-/**
- * chamelium_stream_audio_format:
- *
- * Gets the format used for audio pages.
- *
- * Data will always be captured in raw pages of S32_LE elements. This function
- * exposes the sampling rate and the number of channels.
- */
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels)
-{
-	/* TODO: the Chamelium streaming server doesn't expose those yet.
-	 * Just hardcode the values for now. */
-	*rate = 48000;
-	*channels = 8;
-}
-
 /**
  * chamelium_stream_init:
  *
lib/igt_chamelium_stream.h +0 -2
index de4e9931..3e1c5d14 100644
@@ -42,8 +42,6 @@ struct chamelium_stream *chamelium_stream_init(void);
 void chamelium_stream_deinit(struct chamelium_stream *client);
 bool chamelium_stream_dump_realtime_audio(struct chamelium_stream *client,
 					  enum chamelium_stream_realtime_mode mode);
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels);
 bool chamelium_stream_receive_realtime_audio(struct chamelium_stream *client,
 					     size_t *page_count,
 					     int32_t **buf, size_t *buf_len);
tests/kms_chamelium.c +34 -22

95 lines not on this page · raw message

Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
Reviewed-by on v6 5/7
#11 lore raw

Re: [igt-dev] [PATCH i-g-t v6 5/7] tests/kms_chamelium: run audio test with multiple sampling rates

Quoted 7 lines · Simon Ser

The audio test is now run multiple times with a variety of playback sampling rates.

We now query the capture audio format from the Chamelium XML-RPC API instead of hardcoding it.

One limitation is that we need to start sendting an audio signal before being

Typo on sending.

Quoted 263 lines

able to query the capture audio format. However we need the capture sample rate to decide which frequencies we generate. For now we use the playback rate and check that it's the same as the capture rate.

Another limitation is that the DP receiver reports an unknown sampling rate during the 41.1KHz test. In this case we assume the capture rate is the same as the playback rate. We'll fail later anyway if this assumption is incorrect since we check the signal we receive.

Chameleon bug: https://crbug.com/950913

---
 lib/igt_chamelium.c        | 80 +++++++++++++++++++++++++-------------
 lib/igt_chamelium.h        |  3 ++
 lib/igt_chamelium_stream.c | 17 --------
 lib/igt_chamelium_stream.h |  2 -
 tests/kms_chamelium.c      | 56 +++++++++++++++-----------
 5 files changed, 90 insertions(+), 68 deletions(-)
lib/igt_chamelium.c +53 -27
index 6ac7b722..ffc68f35 100644
@@ -964,31 +964,6 @@ void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 	xmlrpc_DECREF(res);
 }
 
-/**
- * chamelium_start_capturing_audio:
- * @chamelium: the Chamelium instance
- * @port: the port to capture audio from (it must support audio)
- * @save_to_file: whether the captured audio data should be saved to a file on
- * the Chamelium device
- *
- * Starts capturing audio from a Chamelium port. To stop the capture, use
- * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
- * stream server or enable @save_to_file (the latter is mainly useful for
- * debugging purposes).
- *
- * It isn't possible to capture audio from multiple ports at the same time.
- */
-void chamelium_start_capturing_audio(struct chamelium *chamelium,
-				    struct chamelium_port *port,
-				    bool save_to_file)
-{
-	xmlrpc_value *res;
-
-	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
-			    port->id, save_to_file);
-	xmlrpc_DECREF(res);
-}
-
 static void audio_format_from_xml(struct chamelium *chamelium,
 				  xmlrpc_value *res, int *rate, int *channels)
 {
@@ -1008,8 +983,10 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	igt_assert(strcmp(sample_format, "S32_LE") == 0);
 	free(sample_format);
 
-	xmlrpc_read_int(&chamelium->env, res_rate, rate);
-	xmlrpc_read_int(&chamelium->env, res_channel, channels);
+	if (rate)
+		xmlrpc_read_int(&chamelium->env, res_rate, rate);
+	if (channels)
+		xmlrpc_read_int(&chamelium->env, res_channel, channels);
 
 	xmlrpc_DECREF(res_channel);
 	xmlrpc_DECREF(res_sample_format);
@@ -1017,6 +994,55 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	xmlrpc_DECREF(res_type);
 }
 
+/**
+ * chamelium_get_audio_format:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @rate: if non-NULL, will be set to the sample rate in Hz
+ * @channels: if non-NULL, will be set to the number of channels
+ *
+ * Obtains the audio format of the captured data. Users should start sending an
+ * audio signal to the Chamelium device prior to calling this function.
+ *
+ * The captured data is guaranteed to be in the S32_LE format.
+ */
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioFormat", "(i)",
+			    port->id);
+	audio_format_from_xml(chamelium, res, rate, channels);
+	xmlrpc_DECREF(res);
+}
+
+/**
+ * chamelium_start_capturing_audio:
+ * @chamelium: the Chamelium instance
+ * @port: the port to capture audio from (it must support audio)
+ * @save_to_file: whether the captured audio data should be saved to a file on
+ * the Chamelium device
+ *
+ * Starts capturing audio from a Chamelium port. To stop the capture, use
+ * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
+ * stream server or enable @save_to_file (the latter is mainly useful for
+ * debugging purposes).
+ *
+ * It isn't possible to capture audio from multiple ports at the same time.
+ */
+void chamelium_start_capturing_audio(struct chamelium *chamelium,
+				    struct chamelium_port *port,
+				    bool save_to_file)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
+			    port->id, save_to_file);
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_stop_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 728d16ea..f47b84cb 100644
@@ -109,6 +109,9 @@ void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 					 struct chamelium_port *port,
 					 int mapping[static 8]);
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
lib/igt_chamelium_stream.c +0 -17
index 68ddb217..a8cd19e5 100644
@@ -537,23 +537,6 @@ bool chamelium_stream_stop_realtime_audio(struct chamelium_stream *client)
 	return true;
 }
 
-/**
- * chamelium_stream_audio_format:
- *
- * Gets the format used for audio pages.
- *
- * Data will always be captured in raw pages of S32_LE elements. This function
- * exposes the sampling rate and the number of channels.
- */
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels)
-{
-	/* TODO: the Chamelium streaming server doesn't expose those yet.
-	 * Just hardcode the values for now. */
-	*rate = 48000;
-	*channels = 8;
-}
-
 /**
  * chamelium_stream_init:
  *
lib/igt_chamelium_stream.h +0 -2
index de4e9931..3e1c5d14 100644
@@ -42,8 +42,6 @@ struct chamelium_stream *chamelium_stream_init(void);
 void chamelium_stream_deinit(struct chamelium_stream *client);
 bool chamelium_stream_dump_realtime_audio(struct chamelium_stream *client,
 					  enum chamelium_stream_realtime_mode mode);
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels);
 bool chamelium_stream_receive_realtime_audio(struct chamelium_stream *client,
 					     size_t *page_count,
 					     int32_t **buf, size_t *buf_len);
tests/kms_chamelium.c +23 -21
index 8d6cc092..f535ca52 100644
@@ -725,15 +725,14 @@ test_display_frame_dump(data_t *data, struct chamelium_port *port)
 /* A streak of 3 gives confidence that the signal is good. */
 #define MIN_STREAK 3
 
-/* TODO: Chamelium only supports 48KHz for now */
 static int sampling_rates[] = {
-/*	32000, */
-/*	44100, */
+	32000,
+	44100,
 	48000,
-/*	88200, */
-/*	96000, */
-/*	176400, */
-/*	192000, */
+	88200,
+	96000,
+	176400,
+	192000,
 };
 
 static int sampling_rates_count = sizeof(sampling_rates) / sizeof(int);
@@ -815,19 +814,6 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ok = chamelium_stream_dump_realtime_audio(stream, stream_mode);
 	igt_assert(ok);
 
-	chamelium_stream_audio_format(stream, &capture_rate, &capture_channels);
-
-	if (igt_frame_dump_is_enabled()) {
-		snprintf(dump_suffix, sizeof(dump_suffix), "capture-%dch-%d",
-			 playback_channels, playback_rate);
-
-		dump_fd = audio_create_wav_file_s32_le(dump_suffix,
-						       capture_rate,
-						       capture_channels,
-						       &dump_path);
-		igt_assert(dump_fd >= 0);
-	}
-
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
@@ -835,8 +821,12 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	 * independent from each other. To do so, we'll add a different offset
 	 * to the base frequencies for each channel. We need to choose a big
 	 * enough offset so that we're sure to detect mixed up channels.
+	 *
+	 * Note that we assume capture_rate == playback_rate. We'll assert this
+	 * later on. We cannot retrieve the capture rate before starting
+	 * playing audio, so we don't really have the choice.
 	 */
-	step = 2 * capture_rate / CAPTURE_SAMPLES;
+	step = 2 * playback_rate / CAPTURE_SAMPLES;
 	for (i = 0; i < test_frequencies_count; i++) {
 		for (j = 0; j < playback_channels; j++) {
 			freq = test_frequencies[i] + j * step;
@@ -854,6 +844,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
+	/* Only after we've started playing audio, we can retrieve the capture
+	 * format used by the Chamelium device. */
+	chamelium_get_audio_format(data->chamelium, port,
+				   &capture_rate, &capture_channels);
+	if (capture_rate == 0) {
+		igt_debug("Audio receiver doesn't indicate the capture "
+			 "sampling rate, assuming it's %d Hz\n", playback_rate);
+		capture_rate = playback_rate;
+	} else
+		igt_assert(capture_rate == playback_rate);
+
 	chamelium_get_audio_channel_mapping(data->chamelium, port,
 					    channel_mapping);
 	/* Make sure we can capture all channels we send. */
@@ -868,6 +869,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		igt_assert(ok);
 	}
 
+	if (igt_frame_dump_is_enabled()) {

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 882

Quoted 10 lines
tests/kms_chamelium.c +10 -0
+		snprintf(dump_suffix, sizeof(dump_suffix), "capture-%dch-%d",
+			 playback_channels, playback_rate);
+
+		dump_fd = audio_create_wav_file_s32_le(dump_suffix,
+						       capture_rate,
+						       capture_channels,
+						       &dump_path);
+		igt_assert(dump_fd >= 0);
+	}
+

This belongs to another commit.

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 957

Quoted 13 lines
tests/kms_chamelium.c +1 -1
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -939,7 +951,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 
 	if (dump_fd >= 0) {
 		close(dump_fd);
-		if (streak == MIN_STREAK) {
+		if (success) {
 			/* Test succeeded, no need to keep the captured data */
 			unlink(dump_path);
 		} else

Dito.

Otherwise, the code looks OK:

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#12 lore raw

Re: [igt-dev] [PATCH i-g-t v6 5/7] tests/kms_chamelium: run audio test with multiple sampling rates

Quoted 273 lines · Martin Peres
Quoted 7 lines · Simon Ser

The audio test is now run multiple times with a variety of playback sampling rates.

We now query the capture audio format from the Chamelium XML-RPC API instead of hardcoding it.

One limitation is that we need to start sendting an audio signal before being

Typo on sending.

Quoted 262 lines

able to query the capture audio format. However we need the capture sample rate to decide which frequencies we generate. For now we use the playback rate and check that it's the same as the capture rate.

Another limitation is that the DP receiver reports an unknown sampling rate during the 41.1KHz test. In this case we assume the capture rate is the same as the playback rate. We'll fail later anyway if this assumption is incorrect since we check the signal we receive.

Chameleon bug: https://crbug.com/950913

---
 lib/igt_chamelium.c        | 80 +++++++++++++++++++++++++-------------
 lib/igt_chamelium.h        |  3 ++
 lib/igt_chamelium_stream.c | 17 --------
 lib/igt_chamelium_stream.h |  2 -
 tests/kms_chamelium.c      | 56 +++++++++++++++-----------
 5 files changed, 90 insertions(+), 68 deletions(-)
lib/igt_chamelium.c +53 -27
index 6ac7b722..ffc68f35 100644
@@ -964,31 +964,6 @@ void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 	xmlrpc_DECREF(res);
 }
 
-/**
- * chamelium_start_capturing_audio:
- * @chamelium: the Chamelium instance
- * @port: the port to capture audio from (it must support audio)
- * @save_to_file: whether the captured audio data should be saved to a file on
- * the Chamelium device
- *
- * Starts capturing audio from a Chamelium port. To stop the capture, use
- * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
- * stream server or enable @save_to_file (the latter is mainly useful for
- * debugging purposes).
- *
- * It isn't possible to capture audio from multiple ports at the same time.
- */
-void chamelium_start_capturing_audio(struct chamelium *chamelium,
-				    struct chamelium_port *port,
-				    bool save_to_file)
-{
-	xmlrpc_value *res;
-
-	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
-			    port->id, save_to_file);
-	xmlrpc_DECREF(res);
-}
-
 static void audio_format_from_xml(struct chamelium *chamelium,
 				  xmlrpc_value *res, int *rate, int *channels)
 {
@@ -1008,8 +983,10 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	igt_assert(strcmp(sample_format, "S32_LE") == 0);
 	free(sample_format);
 
-	xmlrpc_read_int(&chamelium->env, res_rate, rate);
-	xmlrpc_read_int(&chamelium->env, res_channel, channels);
+	if (rate)
+		xmlrpc_read_int(&chamelium->env, res_rate, rate);
+	if (channels)
+		xmlrpc_read_int(&chamelium->env, res_channel, channels);
 
 	xmlrpc_DECREF(res_channel);
 	xmlrpc_DECREF(res_sample_format);
@@ -1017,6 +994,55 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	xmlrpc_DECREF(res_type);
 }
 
+/**
+ * chamelium_get_audio_format:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @rate: if non-NULL, will be set to the sample rate in Hz
+ * @channels: if non-NULL, will be set to the number of channels
+ *
+ * Obtains the audio format of the captured data. Users should start sending an
+ * audio signal to the Chamelium device prior to calling this function.
+ *
+ * The captured data is guaranteed to be in the S32_LE format.
+ */
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioFormat", "(i)",
+			    port->id);
+	audio_format_from_xml(chamelium, res, rate, channels);
+	xmlrpc_DECREF(res);
+}
+
+/**
+ * chamelium_start_capturing_audio:
+ * @chamelium: the Chamelium instance
+ * @port: the port to capture audio from (it must support audio)
+ * @save_to_file: whether the captured audio data should be saved to a file on
+ * the Chamelium device
+ *
+ * Starts capturing audio from a Chamelium port. To stop the capture, use
+ * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
+ * stream server or enable @save_to_file (the latter is mainly useful for
+ * debugging purposes).
+ *
+ * It isn't possible to capture audio from multiple ports at the same time.
+ */
+void chamelium_start_capturing_audio(struct chamelium *chamelium,
+				    struct chamelium_port *port,
+				    bool save_to_file)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
+			    port->id, save_to_file);
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_stop_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 728d16ea..f47b84cb 100644
@@ -109,6 +109,9 @@ void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 					 struct chamelium_port *port,
 					 int mapping[static 8]);
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
lib/igt_chamelium_stream.c +0 -17
index 68ddb217..a8cd19e5 100644
@@ -537,23 +537,6 @@ bool chamelium_stream_stop_realtime_audio(struct chamelium_stream *client)
 	return true;
 }
 
-/**
- * chamelium_stream_audio_format:
- *
- * Gets the format used for audio pages.
- *
- * Data will always be captured in raw pages of S32_LE elements. This function
- * exposes the sampling rate and the number of channels.
- */
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels)
-{
-	/* TODO: the Chamelium streaming server doesn't expose those yet.
-	 * Just hardcode the values for now. */
-	*rate = 48000;
-	*channels = 8;
-}
-
 /**
  * chamelium_stream_init:
  *
lib/igt_chamelium_stream.h +0 -2
index de4e9931..3e1c5d14 100644
@@ -42,8 +42,6 @@ struct chamelium_stream *chamelium_stream_init(void);
 void chamelium_stream_deinit(struct chamelium_stream *client);
 bool chamelium_stream_dump_realtime_audio(struct chamelium_stream *client,
 					  enum chamelium_stream_realtime_mode mode);
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels);
 bool chamelium_stream_receive_realtime_audio(struct chamelium_stream *client,
 					     size_t *page_count,
 					     int32_t **buf, size_t *buf_len);
tests/kms_chamelium.c +22 -21
index 8d6cc092..f535ca52 100644
@@ -725,15 +725,14 @@ test_display_frame_dump(data_t *data, struct chamelium_port *port)
 /* A streak of 3 gives confidence that the signal is good. */
 #define MIN_STREAK 3
 
-/* TODO: Chamelium only supports 48KHz for now */
 static int sampling_rates[] = {
-/*	32000, */
-/*	44100, */
+	32000,
+	44100,
 	48000,
-/*	88200, */
-/*	96000, */
-/*	176400, */
-/*	192000, */
+	88200,
+	96000,
+	176400,
+	192000,
 };
 
 static int sampling_rates_count = sizeof(sampling_rates) / sizeof(int);
@@ -815,19 +814,6 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ok = chamelium_stream_dump_realtime_audio(stream, stream_mode);
 	igt_assert(ok);
 
-	chamelium_stream_audio_format(stream, &capture_rate, &capture_channels);
-
-	if (igt_frame_dump_is_enabled()) {
-		snprintf(dump_suffix, sizeof(dump_suffix), "capture-%dch-%d",
-			 playback_channels, playback_rate);
-
-		dump_fd = audio_create_wav_file_s32_le(dump_suffix,
-						       capture_rate,
-						       capture_channels,
-						       &dump_path);
-		igt_assert(dump_fd >= 0);
-	}
-
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
@@ -835,8 +821,12 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	 * independent from each other. To do so, we'll add a different offset
 	 * to the base frequencies for each channel. We need to choose a big
 	 * enough offset so that we're sure to detect mixed up channels.
+	 *
+	 * Note that we assume capture_rate == playback_rate. We'll assert this
+	 * later on. We cannot retrieve the capture rate before starting
+	 * playing audio, so we don't really have the choice.
 	 */
-	step = 2 * capture_rate / CAPTURE_SAMPLES;
+	step = 2 * playback_rate / CAPTURE_SAMPLES;
 	for (i = 0; i < test_frequencies_count; i++) {
 		for (j = 0; j < playback_channels; j++) {
 			freq = test_frequencies[i] + j * step;
@@ -854,6 +844,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
+	/* Only after we've started playing audio, we can retrieve the capture
+	 * format used by the Chamelium device. */
+	chamelium_get_audio_format(data->chamelium, port,
+				   &capture_rate, &capture_channels);
+	if (capture_rate == 0) {
+		igt_debug("Audio receiver doesn't indicate the capture "
+			 "sampling rate, assuming it's %d Hz\n", playback_rate);
+		capture_rate = playback_rate;
+	} else
+		igt_assert(capture_rate == playback_rate);
+
 	chamelium_get_audio_channel_mapping(data->chamelium, port,
 					    channel_mapping);
 	/* Make sure we can capture all channels we send. */
@@ -868,6 +869,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		igt_assert(ok);
 	}
 
Quoted 13 lines

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 882

Quoted 11 lines
tests/kms_chamelium.c +11 -0
+	if (igt_frame_dump_is_enabled()) {
+		snprintf(dump_suffix, sizeof(dump_suffix), "capture-%dch-%d",
+			 playback_channels, playback_rate);
+
+		dump_fd = audio_create_wav_file_s32_le(dump_suffix,
+						       capture_rate,
+						       capture_channels,
+						       &dump_path);
+		igt_assert(dump_fd >= 0);
+	}
+

This belongs to another commit.

Nack. This has just been moved around, see line 815 above. This is necessary because of the new chamelium_get_audio_format call.

Quoted 5 lines
Quoted 5 lines
tests/kms_chamelium.c +0 -0
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -939,7 +951,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 
Quoted 10 lines

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 957

Quoted 8 lines
tests/kms_chamelium.c +1 -1
 	if (dump_fd >= 0) {
 		close(dump_fd);
-		if (streak == MIN_STREAK) {
+		if (success) {
 			/* Test succeeded, no need to keep the captured data */
 			unlink(dump_path);
 		} else

Dito.

Ack. Moved to patch 3 "tests/kms_chamelium: test we receive a signal from both audio channels" which introduced this variable.

Quoted 3 lines

Otherwise, the code looks OK:

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#13 lore raw

Re: [igt-dev] [PATCH i-g-t v6 5/7] tests/kms_chamelium: run audio test with multiple sampling rates

Quoted 288 lines · Simon
Quoted 273 lines · Martin Peres
Quoted 7 lines · Simon Ser

The audio test is now run multiple times with a variety of playback sampling rates.

We now query the capture audio format from the Chamelium XML-RPC API instead of hardcoding it.

One limitation is that we need to start sendting an audio signal before being

Typo on sending.

Quoted 262 lines

able to query the capture audio format. However we need the capture sample rate to decide which frequencies we generate. For now we use the playback rate and check that it's the same as the capture rate.

Another limitation is that the DP receiver reports an unknown sampling rate during the 41.1KHz test. In this case we assume the capture rate is the same as the playback rate. We'll fail later anyway if this assumption is incorrect since we check the signal we receive.

Chameleon bug: https://crbug.com/950913

---
 lib/igt_chamelium.c        | 80 +++++++++++++++++++++++++-------------
 lib/igt_chamelium.h        |  3 ++
 lib/igt_chamelium_stream.c | 17 --------
 lib/igt_chamelium_stream.h |  2 -
 tests/kms_chamelium.c      | 56 +++++++++++++++-----------
 5 files changed, 90 insertions(+), 68 deletions(-)
lib/igt_chamelium.c +53 -27
index 6ac7b722..ffc68f35 100644
@@ -964,31 +964,6 @@ void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 	xmlrpc_DECREF(res);
 }
 
-/**
- * chamelium_start_capturing_audio:
- * @chamelium: the Chamelium instance
- * @port: the port to capture audio from (it must support audio)
- * @save_to_file: whether the captured audio data should be saved to a file on
- * the Chamelium device
- *
- * Starts capturing audio from a Chamelium port. To stop the capture, use
- * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
- * stream server or enable @save_to_file (the latter is mainly useful for
- * debugging purposes).
- *
- * It isn't possible to capture audio from multiple ports at the same time.
- */
-void chamelium_start_capturing_audio(struct chamelium *chamelium,
-				    struct chamelium_port *port,
-				    bool save_to_file)
-{
-	xmlrpc_value *res;
-
-	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
-			    port->id, save_to_file);
-	xmlrpc_DECREF(res);
-}
-
 static void audio_format_from_xml(struct chamelium *chamelium,
 				  xmlrpc_value *res, int *rate, int *channels)
 {
@@ -1008,8 +983,10 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	igt_assert(strcmp(sample_format, "S32_LE") == 0);
 	free(sample_format);
 
-	xmlrpc_read_int(&chamelium->env, res_rate, rate);
-	xmlrpc_read_int(&chamelium->env, res_channel, channels);
+	if (rate)
+		xmlrpc_read_int(&chamelium->env, res_rate, rate);
+	if (channels)
+		xmlrpc_read_int(&chamelium->env, res_channel, channels);
 
 	xmlrpc_DECREF(res_channel);
 	xmlrpc_DECREF(res_sample_format);
@@ -1017,6 +994,55 @@ static void audio_format_from_xml(struct chamelium *chamelium,
 	xmlrpc_DECREF(res_type);
 }
 
+/**
+ * chamelium_get_audio_format:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @rate: if non-NULL, will be set to the sample rate in Hz
+ * @channels: if non-NULL, will be set to the number of channels
+ *
+ * Obtains the audio format of the captured data. Users should start sending an
+ * audio signal to the Chamelium device prior to calling this function.
+ *
+ * The captured data is guaranteed to be in the S32_LE format.
+ */
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioFormat", "(i)",
+			    port->id);
+	audio_format_from_xml(chamelium, res, rate, channels);
+	xmlrpc_DECREF(res);
+}
+
+/**
+ * chamelium_start_capturing_audio:
+ * @chamelium: the Chamelium instance
+ * @port: the port to capture audio from (it must support audio)
+ * @save_to_file: whether the captured audio data should be saved to a file on
+ * the Chamelium device
+ *
+ * Starts capturing audio from a Chamelium port. To stop the capture, use
+ * #chamelium_stop_capturing_audio. To retrieve the audio data, either use the
+ * stream server or enable @save_to_file (the latter is mainly useful for
+ * debugging purposes).
+ *
+ * It isn't possible to capture audio from multiple ports at the same time.
+ */
+void chamelium_start_capturing_audio(struct chamelium *chamelium,
+				    struct chamelium_port *port,
+				    bool save_to_file)
+{
+	xmlrpc_value *res;
+
+	res = chamelium_rpc(chamelium, port, "StartCapturingAudio", "(ib)",
+			    port->id, save_to_file);
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_stop_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 728d16ea..f47b84cb 100644
@@ -109,6 +109,9 @@ void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
 					 struct chamelium_port *port,
 					 int mapping[static 8]);
+void chamelium_get_audio_format(struct chamelium *chamelium,
+				struct chamelium_port *port,
+				int *rate, int *channels);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
lib/igt_chamelium_stream.c +0 -17
index 68ddb217..a8cd19e5 100644
@@ -537,23 +537,6 @@ bool chamelium_stream_stop_realtime_audio(struct chamelium_stream *client)
 	return true;
 }
 
-/**
- * chamelium_stream_audio_format:
- *
- * Gets the format used for audio pages.
- *
- * Data will always be captured in raw pages of S32_LE elements. This function
- * exposes the sampling rate and the number of channels.
- */
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels)
-{
-	/* TODO: the Chamelium streaming server doesn't expose those yet.
-	 * Just hardcode the values for now. */
-	*rate = 48000;
-	*channels = 8;
-}
-
 /**
  * chamelium_stream_init:
  *
lib/igt_chamelium_stream.h +0 -2
index de4e9931..3e1c5d14 100644
@@ -42,8 +42,6 @@ struct chamelium_stream *chamelium_stream_init(void);
 void chamelium_stream_deinit(struct chamelium_stream *client);
 bool chamelium_stream_dump_realtime_audio(struct chamelium_stream *client,
 					  enum chamelium_stream_realtime_mode mode);
-void chamelium_stream_audio_format(struct chamelium_stream *stream,
-				   int *rate, int *channels);
 bool chamelium_stream_receive_realtime_audio(struct chamelium_stream *client,
 					     size_t *page_count,
 					     int32_t **buf, size_t *buf_len);
tests/kms_chamelium.c +22 -21
index 8d6cc092..f535ca52 100644
@@ -725,15 +725,14 @@ test_display_frame_dump(data_t *data, struct chamelium_port *port)
 /* A streak of 3 gives confidence that the signal is good. */
 #define MIN_STREAK 3
 
-/* TODO: Chamelium only supports 48KHz for now */
 static int sampling_rates[] = {
-/*	32000, */
-/*	44100, */
+	32000,
+	44100,
 	48000,
-/*	88200, */
-/*	96000, */
-/*	176400, */
-/*	192000, */
+	88200,
+	96000,
+	176400,
+	192000,
 };
 
 static int sampling_rates_count = sizeof(sampling_rates) / sizeof(int);
@@ -815,19 +814,6 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ok = chamelium_stream_dump_realtime_audio(stream, stream_mode);
 	igt_assert(ok);
 
-	chamelium_stream_audio_format(stream, &capture_rate, &capture_channels);
-
-	if (igt_frame_dump_is_enabled()) {
-		snprintf(dump_suffix, sizeof(dump_suffix), "capture-%dch-%d",
-			 playback_channels, playback_rate);
-
-		dump_fd = audio_create_wav_file_s32_le(dump_suffix,
-						       capture_rate,
-						       capture_channels,
-						       &dump_path);
-		igt_assert(dump_fd >= 0);
-	}
-
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
@@ -835,8 +821,12 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	 * independent from each other. To do so, we'll add a different offset
 	 * to the base frequencies for each channel. We need to choose a big
 	 * enough offset so that we're sure to detect mixed up channels.
+	 *
+	 * Note that we assume capture_rate == playback_rate. We'll assert this
+	 * later on. We cannot retrieve the capture rate before starting
+	 * playing audio, so we don't really have the choice.
 	 */
-	step = 2 * capture_rate / CAPTURE_SAMPLES;
+	step = 2 * playback_rate / CAPTURE_SAMPLES;
 	for (i = 0; i < test_frequencies_count; i++) {
 		for (j = 0; j < playback_channels; j++) {
 			freq = test_frequencies[i] + j * step;
@@ -854,6 +844,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
+	/* Only after we've started playing audio, we can retrieve the capture
+	 * format used by the Chamelium device. */
+	chamelium_get_audio_format(data->chamelium, port,
+				   &capture_rate, &capture_channels);
+	if (capture_rate == 0) {
+		igt_debug("Audio receiver doesn't indicate the capture "
+			 "sampling rate, assuming it's %d Hz\n", playback_rate);
+		capture_rate = playback_rate;
+	} else
+		igt_assert(capture_rate == playback_rate);
+
 	chamelium_get_audio_channel_mapping(data->chamelium, port,
 					    channel_mapping);
 	/* Make sure we can capture all channels we send. */
@@ -868,6 +869,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		igt_assert(ok);
 	}
 
Quoted 13 lines

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 882

Quoted 11 lines
tests/kms_chamelium.c +11 -0
+	if (igt_frame_dump_is_enabled()) {
+		snprintf(dump_suffix, sizeof(dump_suffix), "capture-%dch-%d",
+			 playback_channels, playback_rate);
+
+		dump_fd = audio_create_wav_file_s32_le(dump_suffix,
+						       capture_rate,
+						       capture_channels,
+						       &dump_path);
+		igt_assert(dump_fd >= 0);
+	}
+

This belongs to another commit.

Quoted 2 lines

Nack. This has just been moved around, see line 815 above. This is necessary because of the new chamelium_get_audio_format call.

OK, fair enough!

Quoted 17 lines
Quoted 6 lines
Quoted 6 lines
tests/kms_chamelium.c +0 -0
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -939,7 +951,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 
Quoted 10 lines

tests/kms_chamelium.c do_test_display_audio(data_t *data, struct chamelium_port *port, · line 957

Quoted 8 lines
tests/kms_chamelium.c +1 -1
 	if (dump_fd >= 0) {
 		close(dump_fd);
-		if (streak == MIN_STREAK) {
+		if (success) {
 			/* Test succeeded, no need to keep the captured data */
 			unlink(dump_path);
 		} else

Dito.

Quoted 2 lines

Ack. Moved to patch 3 "tests/kms_chamelium: test we receive a signal from both audio channels" which introduced this variable.

OK! Please apply my R-b!

Quoted 4 lines
Quoted 4 lines

Otherwise, the code looks OK:

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#14 lore raw

PATCH v6 6/7 lib/igt_edid: add support for Short Audio Descriptors

In reply to Simon Ser
---
 lib/igt_edid.c | 73 +++++++++++++++++++++++++++++++++++++++-----
 lib/igt_edid.h | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 145 insertions(+), 10 deletions(-)
lib/igt_edid.c +65 -8
index 52e66ab2..3d40d3b3 100644
@@ -252,19 +252,76 @@ void edid_init_with_mode(struct edid *edid, drmModeModeInfo *mode)
 				   EDID_DETAIL_MONITOR_NAME, "IGT");
 }
 
+static uint8_t compute_checksum(const uint8_t *buf, size_t size)
+{
+	size_t i;
+	uint8_t sum = 0;
+
+	assert(size > 0);
+	for (i = 0; i < size - 1; i++) {
+		sum += buf[i];
+	}
+
+	return 256 - sum;
+}
+
 /**
  * edid_update_checksum: compute and update the EDID checksum
  */
 void edid_update_checksum(struct edid *edid)
 {
-	size_t i;
-	const uint8_t *buf = (const uint8_t *) edid;
-	uint8_t sum = 0;
+	edid->checksum = compute_checksum((uint8_t *) edid,
+					  sizeof(struct edid));
+}
 
-	/* calculate checksum */
-	for (i = 0; i < sizeof(struct edid) - 1; i++) {
-		sum = sum + buf[i];
-	}
+/**
+ * cea_sad_init_pcm:
+ * @channels: the number of supported channels (max. 8)
+ * @sampling_rates: bitfield of enum cea_sad_sampling_rate
+ * @sample_sizes: bitfield of enum cea_sad_pcm_sample_size
+ *
+ * Initialize a Short Audio Descriptor to advertise PCM support.
+ */
+void cea_sad_init_pcm(struct cea_sad *sad, int channels,
+		      uint8_t sampling_rates, uint8_t sample_sizes)
+{
+	assert(channels <= 8);
+	sad->format_channels = CEA_SAD_FORMAT_PCM << 3 | (channels - 1);
+	sad->sampling_rates = sampling_rates;
+	sad->bitrate = sample_sizes;
+}
+
+static void edid_cea_finalize(struct edid_cea *cea)
+{
+	cea->checksum = compute_checksum((uint8_t *) cea,
+					 sizeof(struct edid_cea));
+}
+
+/**
+ * edid_ext_set_cea_sad: set an extension block to be CEA SAD
+ */
+void edid_ext_set_cea_sad(struct edid_ext *ext, const struct cea_sad *sads,
+			  size_t sads_len)
+{
+	struct edid_cea *cea = &ext->data.cea;
+	struct edid_cea_data_block *data_block;
+	size_t sads_size, data_block_size;
+
+	memset(ext, 0, sizeof(struct edid_ext));
+
+	sads_size = sizeof(struct cea_sad) * sads_len;
+	data_block_size = sizeof(struct edid_cea_data_block) + sads_size;
+
+	ext->tag = EDID_EXT_CEA;
+
+	cea->revision = 3;
+	cea->dtd_start = 4 + data_block_size;
+	cea->misc = 1 << 6; /* basic audio, no DTD */
+
+	assert(sads_size <= 0xFF);
+	data_block = (struct edid_cea_data_block *) cea->data;
+	data_block->type_len = EDID_CEA_DATA_AUDIO << 5 | sads_size;
+	memcpy(data_block->data.sads, sads, sads_size);
 
-	edid->checksum = 256 - sum;
+	edid_cea_finalize(cea);
 }
lib/igt_edid.h +80 -2

99 lines not on this page · raw message

Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#15 lore raw

PATCH v6 7/7 HAX: add dp-audio test to fast-feedback

In reply to Simon Ser

Waiting for the whole series to be complete to decide whether or not we want this test in fast-feedback.

---
 tests/intel-ci/fast-feedback.testlist | 1 +
 1 file changed, 1 insertion(+)
tests/intel-ci/fast-feedback.testlist +1 -0
index 40475b1a..28f5fa55 100644
@@ -175,6 +175,7 @@ igt@kms_addfb_basic@unused-pitches
 igt@kms_busy@basic-flip-a
 igt@kms_busy@basic-flip-b
 igt@kms_busy@basic-flip-c
+igt@kms_chamelium@dp-audio
 igt@kms_chamelium@dp-hpd-fast
 igt@kms_chamelium@dp-edid-read
 igt@kms_chamelium@dp-crc-fast
Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
#16 lore raw

Re: [igt-dev] [PATCH i-g-t v6 7/7] HAX: add dp-audio test to fast-feedback

Quoted 2 lines · Simon Ser

Waiting for the whole series to be complete to decide whether or not we want this test in fast-feedback.

Let's have a discussion to run these in BAT whenever we have confidence that these tests can be run in less than 10s and work reliably :)

Quoted 12 lines
---
 tests/intel-ci/fast-feedback.testlist | 1 +
 1 file changed, 1 insertion(+)
tests/intel-ci/fast-feedback.testlist +0 -0
index 40475b1a..28f5fa55 100644

tests/intel-ci/fast-feedback.testlist igt@kms_addfb_basic@unused-pitches · line 181

Quoted 7 lines
tests/intel-ci/fast-feedback.testlist +1 -0
@@ -175,6 +175,7 @@ igt@kms_addfb_basic@unused-pitches
 igt@kms_busy@basic-flip-a
 igt@kms_busy@basic-flip-b
 igt@kms_busy@basic-flip-c
+igt@kms_chamelium@dp-audio
 igt@kms_chamelium@dp-hpd-fast
 igt@kms_chamelium@dp-edid-read
 igt@kms_chamelium@dp-crc-fast

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#17 lore raw

[igt-dev] ✗ Fi.CI.BAT: failure for tests/kms_chamelium: add dp-audio test (rev6)

In reply to Simon Ser
== Series Details ==

== Series Details ==

Series: tests/kms_chamelium: add dp-audio test (rev6)
URL : https://patchwork.freedesktop.org/series/59058/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_5946 -> IGTPW_2883
====================================================

Summary
-------

**FAILURE**

Serious unknown changes coming with IGTPW_2883 absolutely need to be verified manually.

If you think the reported changes have nothing to do with the changes introduced in IGTPW_2883, please notify your bug team to allow them to document this new failure mode, which will reduce false positives in CI.

External URL: https://patchwork.freedesktop.org/api/1.0/series/59058/revisions/6/mbox/

Possible new issues
-------------------

Here are the unknown changes that may have been introduced in IGTPW_2883:

### IGT changes ###

#### Possible regressions ####

* igt@amdgpu/amd_prime@i915-to-amd:
- fi-icl-y: NOTRUN -> INCOMPLETE

New tests
---------

New tests have been introduced between CI_DRM_5946 and IGTPW_2883:

### New IGT tests (1) ###

* igt@kms_chamelium@dp-audio:
- Statuses :
- Exec time: [None] s

Known issues
------------

Here are the changes found in IGTPW_2883 that come from known issues:

### IGT changes ###

#### Issues hit ####

* igt@amdgpu/amd_basic@semaphore:
- fi-kbl-7500u: NOTRUN -> SKIP [fdo#109271] +26

* igt@amdgpu/amd_cs_nop@fork-compute0:
- fi-icl-y: NOTRUN -> SKIP [fdo#109315] +15

* igt@gem_ctx_create@basic-files:
- fi-gdg-551: NOTRUN -> SKIP [fdo#109271] +92

* igt@gem_exec_basic@basic-bsd2:
- fi-icl-y: NOTRUN -> SKIP [fdo#109276] +7

* igt@gem_exec_basic@gtt-bsd2:
- fi-byt-clapper: NOTRUN -> SKIP [fdo#109271] +43

* igt@gem_exec_parse@basic-rejected:
- fi-icl-y: NOTRUN -> SKIP [fdo#109289] +1

* igt@kms_busy@basic-flip-a:
- fi-bsw-n3050: NOTRUN -> SKIP [fdo#109271] / [fdo#109278] +1

* igt@kms_busy@basic-flip-c:

    - fi-skl-6770hq:      PASS -> SKIP [fdo#109271] / [fdo#109278] +2
    - fi-blb-e6850:       NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-byt-clapper:     NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-gdg-551:         NOTRUN -> SKIP [fdo#109271] / [fdo#109278]

* igt@kms_flip@basic-flip-vs-dpms:
- fi-skl-6770hq: PASS -> SKIP [fdo#109271] +23

* igt@kms_force_connector_basic@force-load-detect:
- fi-bxt-j4205: NOTRUN -> SKIP [fdo#109271] +38
- fi-icl-y: NOTRUN -> SKIP [fdo#109285] +3

* igt@kms_pipe_crc_basic@hang-read-crc-pipe-a:
- fi-bsw-n3050: NOTRUN -> SKIP [fdo#109271] +48

* igt@kms_psr@primary_mmap_gtt:

    - fi-skl-guc:         NOTRUN -> SKIP [fdo#109271] +38
    - fi-icl-y:           NOTRUN -> SKIP [fdo#110189] +3
    - fi-blb-e6850:       NOTRUN -> SKIP [fdo#109271] +34

* igt@prime_vgem@basic-fence-flip:
- fi-icl-y: NOTRUN -> SKIP [fdo#109294]

#### Possible fixes ####

* igt@gem_exec_suspend@basic-s3:
- fi-blb-e6850: INCOMPLETE [fdo#107718] -> PASS

{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).

[fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
[fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
[fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109294]: https://bugs.freedesktop.org/show_bug.cgi?id=109294
[fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
[fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189

Participating hosts (41 -> 42)
------------------------------

Additional (7): fi-kbl-7567u fi-bsw-n3050 fi-skl-guc fi-bxt-j4205 fi-gdg-551 fi-icl-y fi-byt-clapper
Missing (6): fi-ilk-m540 fi-bsw-cyan fi-icl-u2 fi-skl-6260u fi-ctg-p8600 fi-bdw-samus

Build changes
-------------

* IGT: IGT_4956 -> IGTPW_2883

CI_DRM_5946: 9b74ad002155a574710fccc43f2960855c18ca7c @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_2883: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2883/
IGT_4956: 1d921615b0b706f25c856aa0eb096f274380c199 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Testlist changes ==

-igt@kms_chamelium@common-hpd-after-hibernate -igt@kms_chamelium@common-hpd-after-suspend -igt@kms_chamelium@dp-crc-fast -igt@kms_chamelium@dp-crc-multiple -igt@kms_chamelium@dp-crc-single -igt@kms_chamelium@dp-edid-change-during-hibernate -igt@kms_chamelium@dp-edid-change-during-suspend -igt@kms_chamelium@dp-edid-read -igt@kms_chamelium@dp-frame-dump -igt@kms_chamelium@dp-hpd -igt@kms_chamelium@dp-hpd-after-hibernate -igt@kms_chamelium@dp-hpd-after-suspend -igt@kms_chamelium@dp-hpd-fast -igt@kms_chamelium@dp-hpd-storm -igt@kms_chamelium@dp-hpd-storm-disable -igt@kms_chamelium@hdmi-cmp-nv12 -igt@kms_chamelium@hdmi-cmp-nv16 -igt@kms_chamelium@hdmi-cmp-nv21 -igt@kms_chamelium@hdmi-cmp-nv61 -igt@kms_chamelium@hdmi-cmp-planes-random -igt@kms_chamelium@hdmi-cmp-yu12 -igt@kms_chamelium@hdmi-cmp-yu16 -igt@kms_chamelium@hdmi-cmp-yv12 -igt@kms_chamelium@hdmi-cmp-yv16 -igt@kms_chamelium@hdmi-crc-abgr8888 -igt@kms_chamelium@hdmi-crc-argb1555 -igt@kms_chamelium@hdmi-crc-argb8888 -igt@kms_chamelium@hdmi-crc-bgr565 -igt@kms_chamelium@hdmi-crc-bgr888 -igt@kms_chamelium@hdmi-crc-fast -igt@kms_chamelium@hdmi-crc-multiple -igt@kms_chamelium@hdmi-crc-planes-random -igt@kms_chamelium@hdmi-crc-rgb565 -igt@kms_chamelium@hdmi-crc-rgb888 -igt@kms_chamelium@hdmi-crc-single -igt@kms_chamelium@hdmi-crc-xbgr8888 -igt@kms_chamelium@hdmi-crc-xrgb1555 -igt@kms_chamelium@hdmi-crc-xrgb8888 -igt@kms_chamelium@hdmi-edid-change-during-hibernate -igt@kms_chamelium@hdmi-edid-change-during-suspend -igt@kms_chamelium@hdmi-edid-read -igt@kms_chamelium@hdmi-frame-dump -igt@kms_chamelium@hdmi-hpd -igt@kms_chamelium@hdmi-hpd-after-hibernate -igt@kms_chamelium@hdmi-hpd-after-suspend -igt@kms_chamelium@hdmi-hpd-fast -igt@kms_chamelium@hdmi-hpd-storm -igt@kms_chamelium@hdmi-hpd-storm-disable -igt@kms_chamelium@vga-edid-read -igt@kms_chamelium@vga-frame-dump -igt@kms_chamelium@vga-hpd -igt@kms_chamelium@vga-hpd-after-hibernate -igt@kms_chamelium@vga-hpd-after-suspend -igt@kms_chamelium@vga-hpd-fast -igt@kms_chamelium@vga-hpd-without-ddc

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2883/
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

author
#18 lore raw

Re: [igt-dev] ✗ Fi.CI.BAT: failure for tests/kms_chamelium: add dp-audio test (rev6)

Quoted 46 lines · Patchwork

== Series Details ==

Series: tests/kms_chamelium: add dp-audio test (rev6)
URL : https://patchwork.freedesktop.org/series/59058/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_5946 -> IGTPW_2883
====================================================

Summary
-------

**FAILURE**

Serious unknown changes coming with IGTPW_2883 absolutely need to
be
verified manually.

If you think the reported changes have nothing to do with the
changes
introduced in IGTPW_2883, please notify your bug team to allow them to document this new failure mode, which will reduce false
positives in CI.

External URL:
https://patchwork.freedesktop.org/api/1.0/series/59058/revisions/6/mbox/

Possible new issues
-------------------

Here are the unknown changes that may have been introduced in
IGTPW_2883:

### IGT changes ###

#### Possible regressions ####

* igt@amdgpu/amd_prime@i915-to-amd:
- fi-icl-y: NOTRUN -> INCOMPLETE

New tests
---------

Quoted 7 lines

New tests have been introduced between CI_DRM_5946 and IGTPW_2883:

### New IGT tests (1) ###

* igt@kms_chamelium@dp-audio:
- Statuses :
- Exec time: [None] s

All Chamelium tests were not run because alsa-dev is missing and is now required to build them.

Quoted 162 lines

Known issues
------------

Here are the changes found in IGTPW_2883 that come from known
issues:

### IGT changes ###

#### Issues hit ####

* igt@amdgpu/amd_basic@semaphore:
- fi-kbl-7500u: NOTRUN -> SKIP [fdo#109271] +26

* igt@amdgpu/amd_cs_nop@fork-compute0:
- fi-icl-y: NOTRUN -> SKIP [fdo#109315] +15

* igt@gem_ctx_create@basic-files:
- fi-gdg-551: NOTRUN -> SKIP [fdo#109271] +92

* igt@gem_exec_basic@basic-bsd2:
- fi-icl-y: NOTRUN -> SKIP [fdo#109276] +7

* igt@gem_exec_basic@gtt-bsd2:
- fi-byt-clapper: NOTRUN -> SKIP [fdo#109271] +43

* igt@gem_exec_parse@basic-rejected:
- fi-icl-y: NOTRUN -> SKIP [fdo#109289] +1

* igt@kms_busy@basic-flip-a:
- fi-bsw-n3050: NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
+1

* igt@kms_busy@basic-flip-c:

    - fi-skl-6770hq:      PASS -> SKIP [fdo#109271] / [fdo#109278] +2
    - fi-blb-e6850:       NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-byt-clapper:     NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-gdg-551:         NOTRUN -> SKIP [fdo#109271] / [fdo#109278]

* igt@kms_flip@basic-flip-vs-dpms:
- fi-skl-6770hq: PASS -> SKIP [fdo#109271] +23

* igt@kms_force_connector_basic@force-load-detect:
- fi-bxt-j4205: NOTRUN -> SKIP [fdo#109271] +38
- fi-icl-y: NOTRUN -> SKIP [fdo#109285] +3

* igt@kms_pipe_crc_basic@hang-read-crc-pipe-a:
- fi-bsw-n3050: NOTRUN -> SKIP [fdo#109271] +48

* igt@kms_psr@primary_mmap_gtt:

    - fi-skl-guc:         NOTRUN -> SKIP [fdo#109271] +38
    - fi-icl-y:           NOTRUN -> SKIP [fdo#110189] +3
    - fi-blb-e6850:       NOTRUN -> SKIP [fdo#109271] +34

* igt@prime_vgem@basic-fence-flip:
- fi-icl-y: NOTRUN -> SKIP [fdo#109294]

#### Possible fixes ####

* igt@gem_exec_suspend@basic-s3:
- fi-blb-e6850: INCOMPLETE [fdo#107718] -> PASS

{name}: This element is suppressed. This means it is ignored when
computing
the status of the difference (SUCCESS, WARNING, or
FAILURE).

[fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
[fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
[fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109294]: https://bugs.freedesktop.org/show_bug.cgi?id=109294
[fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
[fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189

Participating hosts (41 -> 42)
------------------------------

Additional (7): fi-kbl-7567u fi-bsw-n3050 fi-skl-guc fi-bxt-j4205
fi-gdg-551 fi-icl-y fi-byt-clapper
Missing (6): fi-ilk-m540 fi-bsw-cyan fi-icl-u2 fi-skl-6260u fi-
ctg-p8600 fi-bdw-samus

Build changes
-------------

* IGT: IGT_4956 -> IGTPW_2883

CI_DRM_5946: 9b74ad002155a574710fccc43f2960855c18ca7c @
git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_2883: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2883/
IGT_4956: 1d921615b0b706f25c856aa0eb096f274380c199 @
git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Testlist changes ==

(quoted diff) +0 -55
-igt@kms_chamelium@common-hpd-after-hibernate
-igt@kms_chamelium@common-hpd-after-suspend
-igt@kms_chamelium@dp-crc-fast
-igt@kms_chamelium@dp-crc-multiple
-igt@kms_chamelium@dp-crc-single
-igt@kms_chamelium@dp-edid-change-during-hibernate
-igt@kms_chamelium@dp-edid-change-during-suspend
-igt@kms_chamelium@dp-edid-read
-igt@kms_chamelium@dp-frame-dump
-igt@kms_chamelium@dp-hpd
-igt@kms_chamelium@dp-hpd-after-hibernate
-igt@kms_chamelium@dp-hpd-after-suspend
-igt@kms_chamelium@dp-hpd-fast
-igt@kms_chamelium@dp-hpd-storm
-igt@kms_chamelium@dp-hpd-storm-disable
-igt@kms_chamelium@hdmi-cmp-nv12
-igt@kms_chamelium@hdmi-cmp-nv16
-igt@kms_chamelium@hdmi-cmp-nv21
-igt@kms_chamelium@hdmi-cmp-nv61
-igt@kms_chamelium@hdmi-cmp-planes-random
-igt@kms_chamelium@hdmi-cmp-yu12
-igt@kms_chamelium@hdmi-cmp-yu16
-igt@kms_chamelium@hdmi-cmp-yv12
-igt@kms_chamelium@hdmi-cmp-yv16
-igt@kms_chamelium@hdmi-crc-abgr8888
-igt@kms_chamelium@hdmi-crc-argb1555
-igt@kms_chamelium@hdmi-crc-argb8888
-igt@kms_chamelium@hdmi-crc-bgr565
-igt@kms_chamelium@hdmi-crc-bgr888
-igt@kms_chamelium@hdmi-crc-fast
-igt@kms_chamelium@hdmi-crc-multiple
-igt@kms_chamelium@hdmi-crc-planes-random
-igt@kms_chamelium@hdmi-crc-rgb565
-igt@kms_chamelium@hdmi-crc-rgb888
-igt@kms_chamelium@hdmi-crc-single
-igt@kms_chamelium@hdmi-crc-xbgr8888
-igt@kms_chamelium@hdmi-crc-xrgb1555
-igt@kms_chamelium@hdmi-crc-xrgb8888
-igt@kms_chamelium@hdmi-edid-change-during-hibernate
-igt@kms_chamelium@hdmi-edid-change-during-suspend
-igt@kms_chamelium@hdmi-edid-read
-igt@kms_chamelium@hdmi-frame-dump
-igt@kms_chamelium@hdmi-hpd
-igt@kms_chamelium@hdmi-hpd-after-hibernate
-igt@kms_chamelium@hdmi-hpd-after-suspend
-igt@kms_chamelium@hdmi-hpd-fast
-igt@kms_chamelium@hdmi-hpd-storm
-igt@kms_chamelium@hdmi-hpd-storm-disable
-igt@kms_chamelium@vga-edid-read
-igt@kms_chamelium@vga-frame-dump
-igt@kms_chamelium@vga-hpd
-igt@kms_chamelium@vga-hpd-after-hibernate
-igt@kms_chamelium@vga-hpd-after-suspend
-igt@kms_chamelium@vga-hpd-fast
-igt@kms_chamelium@vga-hpd-without-ddc
Quoted 4 lines

== Logs ==

For more details see:
https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2883/

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#19 lore raw

[igt-dev] ✓ Fi.CI.BAT: success for tests/kms_chamelium: add dp-audio test (rev7)

In reply to Simon Ser
== Series Details ==

== Series Details ==

Series: tests/kms_chamelium: add dp-audio test (rev7)
URL : https://patchwork.freedesktop.org/series/59058/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5948 -> IGTPW_2887
====================================================

Summary
-------

**SUCCESS**

No regressions found.

External URL: https://patchwork.freedesktop.org/api/1.0/series/59058/revisions/7/mbox/

Possible new issues
-------------------

Here are the unknown changes that may have been introduced in IGTPW_2887:

### IGT changes ###

#### Possible regressions ####

* {igt@kms_chamelium@dp-audio} (NEW):
- fi-kbl-7500u: NOTRUN -> FAIL

New tests
---------

New tests have been introduced between CI_DRM_5948 and IGTPW_2887:

### New IGT tests (1) ###

* igt@kms_chamelium@dp-audio:
- Statuses : 1 fail(s) 37 skip(s)
- Exec time: [0.0, 1.30] s

Known issues
------------

Here are the changes found in IGTPW_2887 that come from known issues:

### IGT changes ###

#### Issues hit ####

* igt@gem_exec_basic@gtt-bsd2:
- fi-byt-clapper: NOTRUN -> SKIP [fdo#109271] +53

* igt@gem_exec_store@basic-bsd2:
- fi-hsw-4770: NOTRUN -> SKIP [fdo#109271] +42

* igt@i915_module_load@reload-with-fault-injection:
- fi-icl-y: PASS -> INCOMPLETE [fdo#107713]

* igt@kms_addfb_basic@addfb25-y-tiled-small:
- fi-byt-n2820: NOTRUN -> SKIP [fdo#109271] +52

* igt@kms_busy@basic-flip-c:

    - fi-byt-j1900:       NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-byt-clapper:     NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-byt-n2820:       NOTRUN -> SKIP [fdo#109271] / [fdo#109278]

* {igt@kms_chamelium@dp-audio} (NEW):

    - fi-skl-6770hq:      NOTRUN -> SKIP [fdo#109271]
    - fi-snb-2600:        NOTRUN -> SKIP [fdo#109271]
    - fi-bwr-2160:        NOTRUN -> SKIP [fdo#109271]
    - fi-skl-lmem:        NOTRUN -> SKIP [fdo#109271]
    - fi-kbl-8809g:       NOTRUN -> SKIP [fdo#109271]
    - fi-kbl-r:           NOTRUN -> SKIP [fdo#109271]
    - fi-apl-guc:         NOTRUN -> SKIP [fdo#109271]
    - {fi-kbl-7567u}:     NOTRUN -> SKIP [fdo#109271]
    - fi-kbl-x1275:       NOTRUN -> SKIP [fdo#109271]
    - fi-icl-y:           NOTRUN -> SKIP [fdo#109284]
    - fi-skl-iommu:       NOTRUN -> SKIP [fdo#109271]
    - fi-blb-e6850:       NOTRUN -> SKIP [fdo#109271]
    - fi-elk-e7500:       NOTRUN -> SKIP [fdo#109271]
    - fi-skl-6700k2:      NOTRUN -> SKIP [fdo#109271]
    - fi-whl-u:           NOTRUN -> SKIP [fdo#109271]
    - fi-bdw-5557u:       NOTRUN -> SKIP [fdo#109271]
    - fi-kbl-guc:         NOTRUN -> SKIP [fdo#109271]
    - fi-cfl-8109u:       NOTRUN -> SKIP [fdo#109271]
    - fi-hsw-4770r:       NOTRUN -> SKIP [fdo#109271]
    - fi-cfl-8700k:       NOTRUN -> SKIP [fdo#109271]
    - fi-glk-dsi:         NOTRUN -> SKIP [fdo#109271]
    - fi-skl-guc:         NOTRUN -> SKIP [fdo#109271]
    - fi-cfl-guc:         NOTRUN -> SKIP [fdo#109271]
    - fi-bdw-gvtdvm:      NOTRUN -> SKIP [fdo#109271]
    - fi-bsw-n3050:       NOTRUN -> SKIP [fdo#109271]
    - fi-ilk-650:         NOTRUN -> SKIP [fdo#109271]
    - fi-ivb-3770:        NOTRUN -> SKIP [fdo#109271]
    - fi-skl-gvtdvm:      NOTRUN -> SKIP [fdo#109271]
    - fi-skl-6260u:       NOTRUN -> SKIP [fdo#109271]
    - fi-bxt-j4205:       NOTRUN -> SKIP [fdo#109271]
    - fi-bxt-dsi:         NOTRUN -> SKIP [fdo#109271]
    - fi-icl-u3:          NOTRUN -> SKIP [fdo#109284]

* igt@kms_chamelium@hdmi-crc-fast:
- fi-byt-j1900: NOTRUN -> SKIP [fdo#109271] +48

* igt@kms_chamelium@hdmi-edid-read:
- fi-hsw-peppy: NOTRUN -> SKIP [fdo#109271] +47

* igt@kms_frontbuffer_tracking@basic:
- fi-hsw-peppy: NOTRUN -> DMESG-FAIL [fdo#102614] / [fdo#107814]
- fi-byt-clapper: NOTRUN -> FAIL [fdo#103167]

#### Possible fixes ####

* igt@i915_selftest@live_execlists:
- fi-apl-guc: INCOMPLETE [fdo#103927] / [fdo#109720] -> PASS

* igt@i915_selftest@live_hangcheck:
- fi-skl-iommu: INCOMPLETE [fdo#108602] / [fdo#108744] -> PASS

{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).

[fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
[fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
[fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
[fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
[fdo#107814]: https://bugs.freedesktop.org/show_bug.cgi?id=107814
[fdo#108602]: https://bugs.freedesktop.org/show_bug.cgi?id=108602
[fdo#108744]: https://bugs.freedesktop.org/show_bug.cgi?id=108744
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
[fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
[fdo#109720]: https://bugs.freedesktop.org/show_bug.cgi?id=109720

Participating hosts (43 -> 40)
------------------------------

Additional (5): fi-byt-j1900 fi-hsw-peppy fi-hsw-4770 fi-byt-n2820 fi-byt-clapper
Missing (8): fi-ilk-m540 fi-byt-squawks fi-snb-2520m fi-ctg-p8600 fi-gdg-551 fi-pnv-d510 fi-bdw-samus fi-skl-6600u

Build changes
-------------

* IGT: IGT_4956 -> IGTPW_2887

CI_DRM_5948: cb5afe9301dbef678a0af3bda9ed9f4ee0b3dbf7 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_2887: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2887/
IGT_4956: 1d921615b0b706f25c856aa0eb096f274380c199 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Testlist changes ==

+igt@kms_chamelium@dp-audio

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2887/
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#20 lore raw

Re: [igt-dev] ✓ Fi.CI.BAT: success for tests/kms_chamelium: add dp-audio test (rev7)

Quoted 23 lines · Patchwork

== Series Details ==

Series: tests/kms_chamelium: add dp-audio test (rev7)
URL : https://patchwork.freedesktop.org/series/59058/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5948 -> IGTPW_2887
====================================================

Summary
-------

**SUCCESS**

No regressions found.

External URL: https://patchwork.freedesktop.org/api/1.0/series/59058/revisions/7/mbox/

Possible new issues
-------------------

Quoted 8 lines

Here are the unknown changes that may have been introduced in IGTPW_2887:

### IGT changes ###

#### Possible regressions ####

* {igt@kms_chamelium@dp-audio} (NEW):
- fi-kbl-7500u: NOTRUN -> FAIL

This is expected because the chamelium in CI has not been updated.

Anyway, outstanding work Simon! Congratulations!

Martin
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#21 lore raw

[igt-dev] ✓ Fi.CI.IGT: success for tests/kms_chamelium: add dp-audio test (rev7)

In reply to Simon Ser
== Series Details ==

== Series Details ==

Series: tests/kms_chamelium: add dp-audio test (rev7)
URL : https://patchwork.freedesktop.org/series/59058/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5948_full -> IGTPW_2887_full
====================================================

Summary
-------

**SUCCESS**

No regressions found.

External URL: https://patchwork.freedesktop.org/api/1.0/series/59058/revisions/7/mbox/

New tests
---------

New tests have been introduced between CI_DRM_5948_full and IGTPW_2887_full:

### New IGT tests (1) ###

* igt@kms_chamelium@dp-audio:
- Statuses : 6 skip(s)
- Exec time: [0.0] s

Known issues
------------

Here are the changes found in IGTPW_2887_full that come from known issues:

### IGT changes ###

#### Issues hit ####

* igt@gem_exec_params@no-blt:
- shard-iclb: NOTRUN -> SKIP [fdo#109283]

* igt@gem_mocs_settings@mocs-rc6-dirty-render:
- shard-iclb: NOTRUN -> SKIP [fdo#110206]

* igt@gem_pwrite@huge-cpu-fbr:
- shard-iclb: NOTRUN -> SKIP [fdo#109290] +1

* igt@gem_stolen@stolen-clear:
- shard-iclb: NOTRUN -> SKIP [fdo#109277]

* igt@gem_tiled_swapping@non-threaded:
- shard-hsw: PASS -> DMESG-WARN [fdo#108686]

* igt@gem_userptr_blits@readonly-pwrite-unsync:
- shard-iclb: NOTRUN -> SKIP [fdo#110426] +1

* igt@gen3_render_mixed_blits:
- shard-iclb: NOTRUN -> SKIP [fdo#109289] +1

* igt@i915_pm_rc6_residency@rc6-accuracy:
- shard-snb: PASS -> SKIP [fdo#109271]

* igt@i915_pm_rpm@dpms-non-lpsp:
- shard-iclb: NOTRUN -> SKIP [fdo#109308]

* igt@i915_pm_rpm@modeset-lpsp-stress:
- shard-apl: NOTRUN -> SKIP [fdo#109271] +119

* igt@i915_pm_sseu@full-enable:
- shard-iclb: NOTRUN -> SKIP [fdo#109288]

* igt@kms_busy@extended-modeset-hang-oldfb-with-reset-render-f:
- shard-kbl: NOTRUN -> SKIP [fdo#109271] / [fdo#109278]

* {igt@kms_chamelium@dp-audio} (NEW):
- shard-glk: NOTRUN -> SKIP [fdo#109271]

* igt@kms_chamelium@hdmi-crc-planes-random:
- shard-iclb: NOTRUN -> SKIP [fdo#109284] +6

* igt@kms_content_protection@atomic:
- shard-apl: NOTRUN -> FAIL [fdo#110321] / [fdo#110336] +1

* igt@kms_cursor_crc@cursor-256x256-suspend:
- shard-kbl: PASS -> DMESG-WARN [fdo#108566]

* igt@kms_cursor_crc@cursor-512x512-suspend:
- shard-iclb: NOTRUN -> SKIP [fdo#109279] +1

* igt@kms_cursor_crc@cursor-64x64-suspend:
- shard-apl: NOTRUN -> DMESG-WARN [fdo#108566]

* igt@kms_cursor_legacy@cursorb-vs-flipb-atomic:
- shard-iclb: NOTRUN -> SKIP [fdo#109274] +4

* igt@kms_flip@2x-flip-vs-expired-vblank-interruptible:
- shard-glk: PASS -> FAIL [fdo#105363]

* igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-render:
- shard-iclb: NOTRUN -> FAIL [fdo#103167]

* igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-blt:
- shard-iclb: PASS -> FAIL [fdo#103167] +8

* igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-render:
- shard-hsw: NOTRUN -> SKIP [fdo#109271] +20

* igt@kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-mmap-wc:
- shard-kbl: NOTRUN -> SKIP [fdo#109271] +3

* igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-blt:
- shard-iclb: NOTRUN -> SKIP [fdo#109280] +26

* igt@kms_frontbuffer_tracking@psr-2p-scndscrn-indfb-msflip-blt:
- shard-snb: NOTRUN -> SKIP [fdo#109271] +75

* igt@kms_lease@setcrtc_implicit_plane:
- shard-apl: NOTRUN -> FAIL [fdo#110281]

* igt@kms_pipe_crc_basic@hang-read-crc-pipe-d:
- shard-hsw: NOTRUN -> SKIP [fdo#109271] / [fdo#109278]

* igt@kms_pipe_crc_basic@hang-read-crc-pipe-e:
- shard-apl: NOTRUN -> SKIP [fdo#109271] / [fdo#109278] +8

* igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
- shard-apl: PASS -> DMESG-WARN [fdo#108566] +2

* igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
- shard-apl: NOTRUN -> FAIL [fdo#108145] +3

* igt@kms_plane_scaling@2x-scaler-multi-pipe:
- shard-iclb: NOTRUN -> SKIP [fdo#109274] / [fdo#109278]

* igt@kms_plane_scaling@pipe-b-scaler-with-clipping-clamping:
- shard-glk: PASS -> SKIP [fdo#109271] / [fdo#109278]

* igt@kms_psr2_su@frontbuffer:
- shard-iclb: PASS -> SKIP [fdo#109642]

* igt@kms_psr@no_drrs:
- shard-iclb: PASS -> FAIL [fdo#108341]

* igt@kms_psr@psr2_primary_mmap_cpu:
- shard-iclb: NOTRUN -> SKIP [fdo#109441] +2

* igt@kms_psr@psr2_primary_page_flip:
- shard-iclb: PASS -> SKIP [fdo#109441] +2

* igt@kms_sysfs_edid_timing:
- shard-iclb: PASS -> FAIL [fdo#100047]

* igt@kms_tv_load_detect@load-detect:
- shard-iclb: NOTRUN -> SKIP [fdo#109309]

* igt@kms_universal_plane@disable-primary-vs-flip-pipe-d:
- shard-snb: NOTRUN -> SKIP [fdo#109271] / [fdo#109278] +5

* igt@kms_universal_plane@universal-plane-gen9-features-pipe-d:
- shard-iclb: NOTRUN -> SKIP [fdo#109278] +3

* igt@perf_pmu@rc6:
- shard-kbl: PASS -> SKIP [fdo#109271]

* igt@prime_nv_api@i915_nv_import_twice_check_flink_name:
- shard-iclb: NOTRUN -> SKIP [fdo#109291] +3

* igt@prime_vgem@fence-wait-bsd1:
- shard-iclb: NOTRUN -> SKIP [fdo#109276] +13

* igt@v3d_get_bo_offset@create-get-offsets:
- shard-iclb: NOTRUN -> SKIP [fdo#109315]

#### Possible fixes ####

* igt@gem_ctx_isolation@bcs0-s3:
- shard-kbl: DMESG-WARN [fdo#108566] -> PASS +2

* igt@gem_eio@in-flight-immediate:
- shard-apl: INCOMPLETE [fdo#103927] -> PASS

* igt@gem_exec_suspend@basic-s3:
- shard-kbl: INCOMPLETE [fdo#103665] -> PASS

* igt@i915_suspend@fence-restore-tiled2untiled:
- shard-apl: DMESG-WARN [fdo#108566] -> PASS +7

* igt@kms_cursor_legacy@2x-long-flip-vs-cursor-atomic:
- shard-glk: FAIL [fdo#104873] -> PASS

* igt@kms_flip@flip-vs-suspend-interruptible:
- shard-hsw: INCOMPLETE [fdo#103540] -> PASS

* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-blt:
- shard-iclb: FAIL [fdo#103167] -> PASS +1

* igt@kms_plane@pixel-format-pipe-c-planes-source-clamping:
- shard-glk: SKIP [fdo#109271] -> PASS

* igt@kms_plane_lowres@pipe-a-tiling-y:
- shard-iclb: FAIL [fdo#103166] -> PASS

* igt@kms_plane_scaling@pipe-a-scaler-with-clipping-clamping:
- shard-glk: SKIP [fdo#109271] / [fdo#109278] -> PASS

* igt@kms_psr2_su@page_flip:
- shard-iclb: SKIP [fdo#109642] -> PASS

* igt@kms_psr@psr2_basic:
- shard-iclb: SKIP [fdo#109441] -> PASS +1

#### Warnings ####

* igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
- shard-apl: INCOMPLETE [fdo#103927] -> SKIP [fdo#109271]

{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).

[fdo#100047]: https://bugs.freedesktop.org/show_bug.cgi?id=100047
[fdo#103166]: https://bugs.freedesktop.org/show_bug.cgi?id=103166
[fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
[fdo#103540]: https://bugs.freedesktop.org/show_bug.cgi?id=103540
[fdo#103665]: https://bugs.freedesktop.org/show_bug.cgi?id=103665
[fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
[fdo#104873]: https://bugs.freedesktop.org/show_bug.cgi?id=104873
[fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
[fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
[fdo#108341]: https://bugs.freedesktop.org/show_bug.cgi?id=108341
[fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
[fdo#108686]: https://bugs.freedesktop.org/show_bug.cgi?id=108686
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
[fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
[fdo#109277]: https://bugs.freedesktop.org/show_bug.cgi?id=109277
[fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
[fdo#109279]: https://bugs.freedesktop.org/show_bug.cgi?id=109279
[fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
[fdo#109283]: https://bugs.freedesktop.org/show_bug.cgi?id=109283
[fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
[fdo#109288]: https://bugs.freedesktop.org/show_bug.cgi?id=109288
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109290]: https://bugs.freedesktop.org/show_bug.cgi?id=109290
[fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
[fdo#109308]: https://bugs.freedesktop.org/show_bug.cgi?id=109308
[fdo#109309]: https://bugs.freedesktop.org/show_bug.cgi?id=109309
[fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
[fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
[fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
[fdo#110206]: https://bugs.freedesktop.org/show_bug.cgi?id=110206
[fdo#110281]: https://bugs.freedesktop.org/show_bug.cgi?id=110281
[fdo#110321]: https://bugs.freedesktop.org/show_bug.cgi?id=110321
[fdo#110336]: https://bugs.freedesktop.org/show_bug.cgi?id=110336
[fdo#110426]: https://bugs.freedesktop.org/show_bug.cgi?id=110426

Participating hosts (10 -> 6)
------------------------------

Missing (4): pig-skl-6260u shard-skl pig-hsw-4770r pig-glk-j5005

Build changes
-------------

* IGT: IGT_4956 -> IGTPW_2887
* Piglit: piglit_4509 -> None

CI_DRM_5948: cb5afe9301dbef678a0af3bda9ed9f4ee0b3dbf7 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_2887: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2887/
IGT_4956: 1d921615b0b706f25c856aa0eb096f274380c199 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2887/
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev