* [igt-dev] [PATCH i-g-t 1/3] lib/igt_infoframe: new library
2019-07-18 7:39 [igt-dev] [PATCH i-g-t 0/3] Chamelium audio InfoFrame tests Simon Ser
@ 2019-07-18 7:39 ` Simon Ser
2019-07-18 7:39 ` [igt-dev] [PATCH i-g-t 2/3] lib/igt_chamelium: add support for GetLastInfoFrame Simon Ser
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Simon Ser @ 2019-07-18 7:39 UTC (permalink / raw)
To: igt-dev
This commit introduces a new igt_infoframe library, used to parse InfoFrames.
For now only audio InfoFrames are supported. Support for AVI and other types of
InfoFrames is planned (and will come with the matching tests).
Unlike igt_edid, InfoFrames are parsed into a higher-level user-friendly
struct.
Signed-off-by: Simon Ser <simon.ser@intel.com>
Reviewed-by: Martin Peres <martin.peres@linux.intel.com>
---
lib/Makefile.sources | 2 +
lib/igt_infoframe.c | 94 ++++++++++++++++++++++++++++++++++++++++++++
lib/igt_infoframe.h | 64 ++++++++++++++++++++++++++++++
lib/meson.build | 1 +
4 files changed, 161 insertions(+)
create mode 100644 lib/igt_infoframe.c
create mode 100644 lib/igt_infoframe.h
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index e16de86eaa08..cf094ab89ac3 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -41,6 +41,8 @@ lib_source_list = \
igt_gvt.h \
igt_halffloat.c \
igt_halffloat.h \
+ igt_infoframe.c \
+ igt_infoframe.h \
igt_matrix.c \
igt_matrix.h \
igt_primes.c \
diff --git a/lib/igt_infoframe.c b/lib/igt_infoframe.c
new file mode 100644
index 000000000000..7e4fb45881a6
--- /dev/null
+++ b/lib/igt_infoframe.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors: Simon Ser <simon.ser@intel.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "igt_infoframe.h"
+
+/**
+ * SECTION:igt_infoframe
+ * @short_description: InfoFrame parsing library
+ * @title: InfoFrame
+ * @include: igt_infoframe.h
+ *
+ * This library provides helpers to parse InfoFrames as defined in CEA-861-D
+ * section 6.
+ */
+
+static const int sampling_freqs[] = {
+ -1, /* refer to stream header */
+ 33000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
+};
+
+static const size_t sampling_freqs_len = sizeof(sampling_freqs) / sizeof(sampling_freqs[0]);
+
+static const int sample_sizes[] = {
+ -1, /* refer to stream header */
+ 16,
+ 20,
+ 24,
+};
+
+static const size_t sample_sizes_len = sizeof(sample_sizes) / sizeof(sample_sizes[0]);
+
+bool infoframe_audio_parse(struct infoframe_audio *infoframe, int version,
+ const uint8_t *buf, size_t buf_size)
+{
+ int channel_count;
+ size_t sampling_freq_idx, sample_size_idx;
+
+ memset(infoframe, 0, sizeof(*infoframe));
+
+ if (version != 1 || buf_size < 5)
+ return false;
+
+ infoframe->coding_type = buf[0] >> 4;
+
+ channel_count = buf[0] & 0x7;
+ if (channel_count == 0)
+ infoframe->channel_count = -1;
+ else
+ infoframe->channel_count = channel_count + 1;
+
+ sampling_freq_idx = (buf[1] >> 2) & 0x7;
+ if (sampling_freq_idx >= sampling_freqs_len)
+ return false;
+ infoframe->sampling_freq = sampling_freqs[sampling_freq_idx];
+
+ sample_size_idx = buf[1] & 0x3;
+ if (sample_size_idx >= sample_sizes_len)
+ return false;
+ infoframe->sample_size = sample_sizes[sample_size_idx];
+
+ return true;
+}
diff --git a/lib/igt_infoframe.h b/lib/igt_infoframe.h
new file mode 100644
index 000000000000..35daa3ea169d
--- /dev/null
+++ b/lib/igt_infoframe.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors: Simon Ser <simon.ser@intel.com>
+ */
+
+#ifndef IGT_INFOFRAME_H
+#define IGT_INFOFRAME_H
+
+#include "config.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+enum infoframe_audio_coding_type {
+ INFOFRAME_AUDIO_CT_UNSPECIFIED = 0, /* refer to stream header */
+ INFOFRAME_AUDIO_CT_PCM = 1, /* IEC 60958 PCM */
+ INFOFRAME_AUDIO_CT_AC3 = 2,
+ INFOFRAME_AUDIO_CT_MPEG1 = 3,
+ INFOFRAME_AUDIO_CT_MP3 = 4,
+ INFOFRAME_AUDIO_CT_MPEG2 = 5,
+ INFOFRAME_AUDIO_CT_AAC = 6,
+ INFOFRAME_AUDIO_CT_DTS = 7,
+ INFOFRAME_AUDIO_CT_ATRAC = 8,
+ INFOFRAME_AUDIO_CT_ONE_BIT = 9,
+ INFOFRAME_AUDIO_CT_DOLBY = 10, /* Dolby Digital + */
+ INFOFRAME_AUDIO_CT_DTS_HD = 11,
+ INFOFRAME_AUDIO_CT_MAT = 12,
+ INFOFRAME_AUDIO_CT_DST = 13,
+ INFOFRAME_AUDIO_CT_WMA_PRO = 14,
+};
+
+struct infoframe_audio {
+ enum infoframe_audio_coding_type coding_type;
+ int channel_count; /* -1 if unspecified */
+ int sampling_freq; /* in Hz, -1 if unspecified */
+ int sample_size; /* in bits, -1 if unspecified */
+ /* TODO: speaker allocation */
+};
+
+bool infoframe_audio_parse(struct infoframe_audio *infoframe, int version,
+ const uint8_t *buf, size_t buf_size);
+
+#endif
diff --git a/lib/meson.build b/lib/meson.build
index 157624e71952..221ae28c084b 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -61,6 +61,7 @@ lib_sources = [
'igt_amd.c',
'igt_edid.c',
'igt_eld.c',
+ 'igt_infoframe.c',
]
lib_deps = [
--
2.22.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 6+ messages in thread* [igt-dev] [PATCH i-g-t 2/3] lib/igt_chamelium: add support for GetLastInfoFrame
2019-07-18 7:39 [igt-dev] [PATCH i-g-t 0/3] Chamelium audio InfoFrame tests Simon Ser
2019-07-18 7:39 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_infoframe: new library Simon Ser
@ 2019-07-18 7:39 ` Simon Ser
2019-07-18 7:39 ` [igt-dev] [PATCH i-g-t 3/3] tests/kms_chamelium: add InfoFrame checks to audio tests Simon Ser
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Simon Ser @ 2019-07-18 7:39 UTC (permalink / raw)
To: igt-dev
This new call retrieves the last InfoFrame received by the Chamelium board.
Signed-off-by: Simon Ser <simon.ser@intel.com>
Reviewed-by: Martin Peres <martin.peres@linux.intel.com>
---
lib/igt_chamelium.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
lib/igt_chamelium.h | 19 +++++++++++++++
2 files changed, 76 insertions(+)
diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index 3803a90e4250..bd9e83d43571 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -1045,6 +1045,63 @@ int chamelium_get_captured_frame_count(struct chamelium *chamelium)
return ret;
}
+bool chamelium_supports_get_last_infoframe(struct chamelium *chamelium)
+{
+ return chamelium_supports_method(chamelium, "GetLastInfoFrame");
+}
+
+static const char *
+chamelium_infoframe_type_str(enum chamelium_infoframe_type type)
+{
+ switch (type) {
+ case CHAMELIUM_INFOFRAME_AVI:
+ return "avi";
+ case CHAMELIUM_INFOFRAME_AUDIO:
+ return "audio";
+ case CHAMELIUM_INFOFRAME_MPEG:
+ return "mpeg";
+ case CHAMELIUM_INFOFRAME_VENDOR:
+ return "vendor";
+ }
+ assert(0); /* unreachable */
+}
+
+struct chamelium_infoframe *
+chamelium_get_last_infoframe(struct chamelium *chamelium,
+ struct chamelium_port *port,
+ enum chamelium_infoframe_type type)
+{
+ xmlrpc_value *res, *res_version, *res_payload;
+ struct chamelium_infoframe *infoframe;
+ const unsigned char *payload;
+
+ res = chamelium_rpc(chamelium, NULL, "GetLastInfoFrame", "(is)",
+ port->id, chamelium_infoframe_type_str(type));
+ xmlrpc_struct_find_value(&chamelium->env, res, "version", &res_version);
+ xmlrpc_struct_find_value(&chamelium->env, res, "payload", &res_payload);
+ infoframe = calloc(1, sizeof(*infoframe));
+ xmlrpc_read_int(&chamelium->env, res_version, &infoframe->version);
+ xmlrpc_read_base64(&chamelium->env, res_payload,
+ &infoframe->payload_size, &payload);
+ /* xmlrpc-c's docs say payload is actually not constant */
+ infoframe->payload = (uint8_t *) payload;
+ xmlrpc_DECREF(res_version);
+ xmlrpc_DECREF(res_payload);
+ xmlrpc_DECREF(res);
+
+ if (infoframe->payload_size == 0) {
+ chamelium_infoframe_destroy(infoframe);
+ return NULL;
+ }
+ return infoframe;
+}
+
+void chamelium_infoframe_destroy(struct chamelium_infoframe *infoframe)
+{
+ free(infoframe->payload);
+ free(infoframe);
+}
+
bool chamelium_has_audio_support(struct chamelium *chamelium,
struct chamelium_port *port)
{
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index 8b4fc3344c64..34dba312f729 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -65,6 +65,19 @@ struct chamelium_audio_file {
int channels;
};
+enum chamelium_infoframe_type {
+ CHAMELIUM_INFOFRAME_AVI,
+ CHAMELIUM_INFOFRAME_AUDIO,
+ CHAMELIUM_INFOFRAME_MPEG,
+ CHAMELIUM_INFOFRAME_VENDOR,
+};
+
+struct chamelium_infoframe {
+ int version;
+ size_t payload_size;
+ uint8_t *payload;
+};
+
struct chamelium_edid;
/**
@@ -132,6 +145,11 @@ 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);
+bool chamelium_supports_get_last_infoframe(struct chamelium *chamelium);
+struct chamelium_infoframe *
+chamelium_get_last_infoframe(struct chamelium *chamelium,
+ struct chamelium_port *port,
+ enum chamelium_infoframe_type type);
bool chamelium_has_audio_support(struct chamelium *chamelium,
struct chamelium_port *port);
void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
@@ -176,5 +194,6 @@ 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);
+void chamelium_infoframe_destroy(struct chamelium_infoframe *infoframe);
#endif /* IGT_CHAMELIUM_H */
--
2.22.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 6+ messages in thread* [igt-dev] [PATCH i-g-t 3/3] tests/kms_chamelium: add InfoFrame checks to audio tests
2019-07-18 7:39 [igt-dev] [PATCH i-g-t 0/3] Chamelium audio InfoFrame tests Simon Ser
2019-07-18 7:39 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_infoframe: new library Simon Ser
2019-07-18 7:39 ` [igt-dev] [PATCH i-g-t 2/3] lib/igt_chamelium: add support for GetLastInfoFrame Simon Ser
@ 2019-07-18 7:39 ` Simon Ser
2019-07-18 8:19 ` [igt-dev] ✓ Fi.CI.BAT: success for Chamelium audio InfoFrame tests (rev2) Patchwork
2019-07-18 10:54 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
4 siblings, 0 replies; 6+ messages in thread
From: Simon Ser @ 2019-07-18 7:39 UTC (permalink / raw)
To: igt-dev
If the DUT sends an InfoFrame, check that its values are correct. Per the HDMI
and DP specs, most of the fields can be set to "refer to stream header" because
some information is duplicated. The DP spec also says that InfoFrames are
optional if mono or stereo audio is used (because there's no channel speaker
allocation).
Signed-off-by: Simon Ser <simon.ser@intel.com>
Reviewed-by: Martin Peres <martin.peres@linux.intel.com>
---
tests/kms_chamelium.c | 56 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index aaf539b705b7..04ad9cf0a3ad 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -29,6 +29,7 @@
#include "igt_vc4.h"
#include "igt_edid.h"
#include "igt_eld.h"
+#include "igt_infoframe.h"
#include <fcntl.h>
#include <pthread.h>
@@ -1118,6 +1119,59 @@ static void audio_state_stop(struct audio_state *state, bool success)
success ? "ALL GREEN" : "FAILED");
}
+static void check_audio_infoframe(struct audio_state *state)
+{
+ struct chamelium_infoframe *infoframe;
+ struct infoframe_audio infoframe_audio;
+ struct infoframe_audio expected = {0};
+ bool ok;
+
+ if (!chamelium_supports_get_last_infoframe(state->chamelium)) {
+ igt_debug("Skipping audio InfoFrame check: "
+ "Chamelium board doesn't support GetLastInfoFrame\n");
+ return;
+ }
+
+ expected.coding_type = INFOFRAME_AUDIO_CT_PCM;
+ expected.channel_count = state->playback.channels;
+ expected.sampling_freq = state->playback.rate;
+ expected.sample_size = snd_pcm_format_width(state->playback.format);
+
+ infoframe = chamelium_get_last_infoframe(state->chamelium, state->port,
+ CHAMELIUM_INFOFRAME_AUDIO);
+ if (infoframe == NULL && state->playback.channels <= 2) {
+ /* Audio InfoFrames are optional for mono and stereo audio */
+ igt_debug("Skipping audio InfoFrame check: "
+ "no InfoFrame received\n");
+ return;
+ }
+ igt_assert_f(infoframe != NULL, "no audio InfoFrame received\n");
+
+ ok = infoframe_audio_parse(&infoframe_audio, infoframe->version,
+ infoframe->payload, infoframe->payload_size);
+ chamelium_infoframe_destroy(infoframe);
+ igt_assert_f(ok, "failed to parse audio InfoFrame\n");
+
+ igt_debug("Checking audio InfoFrame:\n");
+ igt_debug("coding_type: got %d, expected %d\n",
+ infoframe_audio.coding_type, expected.coding_type);
+ igt_debug("channel_count: got %d, expected %d\n",
+ infoframe_audio.channel_count, expected.channel_count);
+ igt_debug("sampling_freq: got %d, expected %d\n",
+ infoframe_audio.sampling_freq, expected.sampling_freq);
+ igt_debug("sample_size: got %d, expected %d\n",
+ infoframe_audio.sample_size, expected.sample_size);
+
+ if (infoframe_audio.coding_type != INFOFRAME_AUDIO_CT_UNSPECIFIED)
+ igt_assert(infoframe_audio.coding_type == expected.coding_type);
+ if (infoframe_audio.channel_count >= 0)
+ igt_assert(infoframe_audio.channel_count == expected.channel_count);
+ if (infoframe_audio.sampling_freq >= 0)
+ igt_assert(infoframe_audio.sampling_freq == expected.sampling_freq);
+ if (infoframe_audio.sample_size >= 0)
+ igt_assert(infoframe_audio.sample_size == expected.sample_size);
+}
+
static int
audio_output_frequencies_callback(void *data, void *buffer, int samples)
{
@@ -1243,6 +1297,8 @@ static bool test_audio_frequencies(struct audio_state *state)
free(channel);
audio_signal_fini(state->signal);
+ check_audio_infoframe(state);
+
return success;
}
--
2.22.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 6+ messages in thread