summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2020-03-08 16:05:07 +0100
committerEugene Syromyatnikov <evgsyr@gmail.com>2020-03-23 13:32:15 +0100
commite20a64ed3d3c63d954e1e7f610bded40f718db89 (patch)
tree63fe6f8206d223a1ac90d814324331648698ead3
parent8221273a26e27cc8ea2dc48a8e317a0fa908b6d9 (diff)
downloadstrace-e20a64ed3d3c63d954e1e7f610bded40f718db89.tar.gz
v4l2: implement struct v4l2_audio and v4l2_audioout decoding
-rw-r--r--tests/ioctl_v4l2-success.c154
-rw-r--r--tests/ioctl_v4l2.c131
-rw-r--r--v4l2.c140
-rw-r--r--xlat/v4l2_audio_capabilities.in2
-rw-r--r--xlat/v4l2_audio_modes.in1
-rw-r--r--xlat/v4l2_ioctl_cmds.in12
6 files changed, 428 insertions, 12 deletions
diff --git a/tests/ioctl_v4l2-success.c b/tests/ioctl_v4l2-success.c
index bddbebc09..9e8f49f64 100644
--- a/tests/ioctl_v4l2-success.c
+++ b/tests/ioctl_v4l2-success.c
@@ -1472,6 +1472,83 @@ main(int argc, char **argv)
}
+ /* VIDIOC_G_AUDIO, VIDIOC_S_AUDIO, VIDIOC_ENUMAUDIO */
+ static const struct strval32 audio_cmds[] = {
+ { ARG_STR(VIDIOC_G_AUDIO) },
+ { ARG_STR(VIDIOC_S_AUDIO) },
+ { ARG_STR(VIDIOC_ENUMAUDIO) },
+ };
+ static const struct strval32 audio_caps[] = {
+ { ARG_STR(0) },
+ { ARG_XLAT_KNOWN(0x1, "V4L2_AUDCAP_STEREO") },
+ { ARG_XLAT_KNOWN(0x2, "V4L2_AUDCAP_AVL") },
+ { ARG_XLAT_KNOWN(0xdeadbeef, "V4L2_AUDCAP_STEREO"
+ "|V4L2_AUDCAP_AVL|0xdeadbeec") },
+ { ARG_XLAT_UNKNOWN(0xdec0dedc, "V4L2_AUDCAP_???") },
+ };
+ static const struct strval32 audio_modes[] = {
+ { ARG_STR(0) },
+ { ARG_XLAT_KNOWN(0x1, "V4L2_AUDMODE_AVL") },
+ { ARG_XLAT_KNOWN(0xfeedbeef, "V4L2_AUDMODE_AVL|0xfeedbeee") },
+ { ARG_XLAT_UNKNOWN(0xdeadface, "V4L2_AUDMODE_???") },
+ };
+ static const size_t audio_iters = MAX(ARRAY_SIZE(audio_caps),
+ ARRAY_SIZE(audio_modes));
+
+ struct v4l2_audio *audio = tail_alloc(sizeof(*audio));
+
+ for (size_t i = 0; i < ARRAY_SIZE(audio_cmds); i++) {
+ ioctl(-1, audio_cmds[i].val, 0);
+ printf("ioctl(-1, %s, NULL) = %ld (INJECTED)\n",
+ sprintxlat(audio_cmds[i].str, audio_cmds[i].val, NULL),
+ inject_retval);
+
+ ioctl(-1, audio_cmds[i].val, (char *) audio + 1);
+ printf("ioctl(-1, %s, %p) = %ld (INJECTED)\n",
+ sprintxlat(audio_cmds[i].str, audio_cmds[i].val, NULL),
+ (char *) audio + 1, inject_retval);
+
+ for (size_t j = 0; j < audio_iters; j++) {
+ fill_memory32(audio, sizeof(*audio));
+ fill_memory_ex(audio->name, sizeof(audio->name),
+ j * 39 + 5, 255);
+ audio->capability =
+ audio_caps[j % ARRAY_SIZE(audio_caps)].val;
+ audio->mode =
+ audio_modes[j % ARRAY_SIZE(audio_modes)].val;
+
+ if ((i + j) % 2)
+ memset(audio->reserved, 0,
+ sizeof(audio->reserved));
+
+ ioctl(-1, audio_cmds[i].val, audio);
+ printf("ioctl(-1, %s, %s{index=2158018784",
+ sprintxlat(audio_cmds[i].str,
+ audio_cmds[i].val, NULL),
+ (audio_cmds[i].val == VIDIOC_G_AUDIO) &&
+ !((i + j) % 2) ? "{reserved=[0x80a0c0eb"
+ ", 0x80a0c0ec]} => " : "");
+ if (audio_cmds[i].val != VIDIOC_S_AUDIO) {
+ printf("%sname=",
+ audio_cmds[i].val == VIDIOC_G_AUDIO
+ ? ", " : (i + j) % 2 ? "} => {"
+ : ", reserved=[0x80a0c0eb"
+ ", 0x80a0c0ec]} => {");
+ print_quoted_cstring((char *) audio->name,
+ sizeof(audio->name));
+ printf(", capability=%s",
+ audio_caps[j %
+ ARRAY_SIZE(audio_caps)].str);
+ }
+ printf(", mode=%s%s}) = %ld (INJECTED)\n",
+ audio_modes[j % ARRAY_SIZE(audio_modes)].str,
+ (i + j) % 2 ? "" : ", reserved=[0x80a0c0eb"
+ ", 0x80a0c0ec]",
+ inject_retval);
+ }
+ }
+
+
/* VIDIOC_QUERYCTRL */
static const struct strval32 cids[] = {
{ ARG_XLAT_UNKNOWN(0, "V4L2_CID_???") },
@@ -1657,6 +1734,83 @@ main(int argc, char **argv)
}
+ /* VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT, VIDIOC_ENUMAUDOUT */
+ static const struct strval32 audout_cmds[] = {
+ { ARG_STR(VIDIOC_G_AUDOUT) },
+ { ARG_STR(VIDIOC_S_AUDOUT) },
+ { ARG_STR(VIDIOC_ENUMAUDOUT) },
+ };
+ static const struct strval32 audout_caps[] = {
+ { ARG_STR(0) },
+ { ARG_STR(0x1) },
+ { ARG_STR(0x2) },
+ { ARG_STR(0xdeadbeef) },
+ { ARG_STR(0xdec0dedc) },
+ };
+ static const struct strval32 audout_modes[] = {
+ { ARG_STR(0) },
+ { ARG_STR(0x1) },
+ { ARG_STR(0xfeadbeef) },
+ { ARG_STR(0xdeadface) },
+ };
+ static const size_t audout_iters = MAX(ARRAY_SIZE(audout_caps),
+ ARRAY_SIZE(audout_modes));
+
+ struct v4l2_audioout *audout = tail_alloc(sizeof(*audout));
+
+ for (size_t i = 0; i < ARRAY_SIZE(audout_cmds); i++) {
+ ioctl(-1, audout_cmds[i].val, 0);
+ printf("ioctl(-1, %s, NULL) = %ld (INJECTED)\n",
+ sprintxlat(audout_cmds[i].str, audout_cmds[i].val, NULL),
+ inject_retval);
+
+ ioctl(-1, audout_cmds[i].val, (char *) audout + 1);
+ printf("ioctl(-1, %s, %p) = %ld (INJECTED)\n",
+ sprintxlat(audout_cmds[i].str, audout_cmds[i].val, NULL),
+ (char *) audout + 1, inject_retval);
+
+ for (size_t j = 0; j < audout_iters; j++) {
+ fill_memory32(audout, sizeof(*audout));
+ fill_memory_ex(audout->name, sizeof(audout->name),
+ j * 39 + 5, 255);
+ audout->capability =
+ audout_caps[j % ARRAY_SIZE(audout_caps)].val;
+ audout->mode =
+ audout_modes[j % ARRAY_SIZE(audout_modes)].val;
+
+ if ((i + j) % 2)
+ memset(audout->reserved, 0,
+ sizeof(audout->reserved));
+
+ ioctl(-1, audout_cmds[i].val, audout);
+ printf("ioctl(-1, %s, %s{index=2158018784",
+ sprintxlat(audout_cmds[i].str,
+ audout_cmds[i].val, NULL),
+ (audout_cmds[i].val == VIDIOC_G_AUDOUT) &&
+ !((i + j) % 2) ? "{reserved=[0x80a0c0eb"
+ ", 0x80a0c0ec]} => " : "");
+ if (audout_cmds[i].val != VIDIOC_S_AUDOUT) {
+ printf("%sname=",
+ audout_cmds[i].val == VIDIOC_G_AUDOUT
+ ? ", " : (i + j) % 2 ? "} => {"
+ : ", reserved=[0x80a0c0eb"
+ ", 0x80a0c0ec]} => {");
+ print_quoted_cstring((char *) audout->name,
+ sizeof(audout->name));
+ printf(", capability=%s, mode=%s",
+ audout_caps[j %
+ ARRAY_SIZE(audout_caps)].str,
+ audout_modes[j %
+ ARRAY_SIZE(audout_modes)].str);
+ }
+ printf("%s}) = %ld (INJECTED)\n",
+ (i + j) % 2 ? "" : ", reserved=[0x80a0c0eb"
+ ", 0x80a0c0ec]",
+ inject_retval);
+ }
+ }
+
+
/* VIDIOC_CROPCAP */
struct v4l2_cropcap *ccap = tail_alloc(sizeof(*ccap));
diff --git a/tests/ioctl_v4l2.c b/tests/ioctl_v4l2.c
index f3c582946..6e9e39176 100644
--- a/tests/ioctl_v4l2.c
+++ b/tests/ioctl_v4l2.c
@@ -570,8 +570,6 @@ main(void)
uint32_t cmd;
const char *str;
} unsupp_cmds[] = {
- { ARG_STR(VIDIOC_G_AUDIO) },
- { ARG_STR(VIDIOC_S_AUDIO) },
#ifdef VIDIOC_G_EDID
{ ARG_STR(VIDIOC_G_EDID) },
#endif
@@ -579,16 +577,12 @@ main(void)
{ ARG_STR(VIDIOC_S_EDID) },
#endif
{ ARG_STR(VIDIOC_ENUMOUTPUT) },
- { ARG_STR(VIDIOC_G_AUDOUT) },
- { ARG_STR(VIDIOC_S_AUDOUT) },
{ ARG_STR(VIDIOC_G_MODULATOR) },
{ ARG_STR(VIDIOC_S_MODULATOR) },
{ ARG_STR(VIDIOC_G_FREQUENCY) },
{ ARG_STR(VIDIOC_S_FREQUENCY) },
{ ARG_STR(VIDIOC_G_JPEGCOMP) },
{ ARG_STR(VIDIOC_S_JPEGCOMP) },
- { ARG_STR(VIDIOC_ENUMAUDIO) },
- { ARG_STR(VIDIOC_ENUMAUDOUT) },
{ ARG_STR(VIDIOC_G_SLICED_VBI_CAP) },
#ifdef VIDIOC_G_ENC_INDEX
{ ARG_STR(VIDIOC_G_ENC_INDEX) },
@@ -1321,6 +1315,95 @@ main(void)
p_tuner->reserved[0], p_tuner->reserved[1],
p_tuner->reserved[2], p_tuner->reserved[3]);
+ /* VIDIOC_G_AUDIO */
+ ioctl(-1, VIDIOC_G_AUDIO, 0);
+ printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_G_AUDIO));
+
+ struct v4l2_audio *const p_v4l2_audio =
+ tail_alloc(sizeof(*p_v4l2_audio));
+ fill_memory32(p_v4l2_audio, sizeof(*p_v4l2_audio));
+ ioctl(-1, VIDIOC_G_AUDIO, p_v4l2_audio);
+ printf("ioctl(-1, %s, {reserved=[0x80a0c0eb, 0x80a0c0ec]}"
+ ") = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_G_AUDIO));
+
+ memset(p_v4l2_audio->reserved, 0, sizeof(p_v4l2_audio->reserved));
+ ioctl(-1, VIDIOC_G_AUDIO, p_v4l2_audio);
+ printf("ioctl(-1, %s, %p) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_G_AUDIO), p_v4l2_audio);
+
+ /* VIDIOC_S_AUDIO */
+ ioctl(-1, VIDIOC_S_AUDIO, 0);
+ printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_S_AUDIO));
+
+ fill_memory32(p_v4l2_audio, sizeof(*p_v4l2_audio));
+ strcpy((char *) p_v4l2_audio->name, "cum tacent, clamant");
+ p_v4l2_audio->index = 0xfacebeef;
+ p_v4l2_audio->capability = V4L2_AUDCAP_STEREO | V4L2_AUDCAP_AVL;
+ p_v4l2_audio->mode = V4L2_AUDMODE_AVL;
+
+ ioctl(-1, VIDIOC_S_AUDIO, p_v4l2_audio);
+ printf("ioctl(-1, %s, {index=%u, mode=" XLAT_FMT
+ ", reserved=[%#x, %#x]}) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_S_AUDIO), p_v4l2_audio->index,
+ XLAT_ARGS(V4L2_AUDMODE_AVL),
+ p_v4l2_audio->reserved[0], p_v4l2_audio->reserved[1]);
+
+ memset(p_v4l2_audio->reserved, 0, sizeof(p_v4l2_audio->reserved));
+ p_v4l2_audio->index = 0;
+ p_v4l2_audio->capability = 0xbeef0d1c;
+ p_v4l2_audio->mode = 0xdeadface;
+ ioctl(-1, VIDIOC_S_AUDIO, p_v4l2_audio);
+ printf("ioctl(-1, %s, {index=0, mode=%#x"
+ NRAW(" /* V4L2_AUDMODE_??? */") "}) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_S_AUDIO), p_v4l2_audio->mode);
+
+ /* VIDIOC_G_AUDOUT */
+ ioctl(-1, VIDIOC_G_AUDOUT, 0);
+ printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_G_AUDOUT));
+
+ struct v4l2_audioout *const p_v4l2_audioout =
+ tail_alloc(sizeof(*p_v4l2_audioout));
+ fill_memory32(p_v4l2_audioout, sizeof(*p_v4l2_audioout));
+ ioctl(-1, VIDIOC_G_AUDOUT, p_v4l2_audioout);
+ printf("ioctl(-1, %s, {reserved=[0x80a0c0eb, 0x80a0c0ec]}"
+ ") = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_G_AUDOUT));
+
+ memset(p_v4l2_audioout->reserved, 0, sizeof(p_v4l2_audioout->reserved));
+ ioctl(-1, VIDIOC_G_AUDOUT, p_v4l2_audioout);
+ printf("ioctl(-1, %s, %p) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_G_AUDOUT), p_v4l2_audioout);
+
+ /* VIDIOC_S_AUDOUT */
+ ioctl(-1, VIDIOC_S_AUDOUT, 0);
+ printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_S_AUDOUT));
+
+ fill_memory32(p_v4l2_audioout, sizeof(*p_v4l2_audioout));
+ strcpy((char *) p_v4l2_audioout->name, "cum tacent, clamant");
+ p_v4l2_audioout->index = 0xfacebeef;
+ /* NB: These are for v4l2_audio only and not for v4l2_audioout */
+ p_v4l2_audioout->capability = V4L2_AUDCAP_STEREO | V4L2_AUDCAP_AVL;
+ p_v4l2_audioout->mode = V4L2_AUDMODE_AVL;
+
+ ioctl(-1, VIDIOC_S_AUDOUT, p_v4l2_audioout);
+ printf("ioctl(-1, %s, {index=%u, reserved=[%#x, %#x]}"
+ ") = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_S_AUDOUT), p_v4l2_audioout->index,
+ p_v4l2_audioout->reserved[0], p_v4l2_audioout->reserved[1]);
+
+ memset(p_v4l2_audioout->reserved, 0, sizeof(p_v4l2_audioout->reserved));
+ p_v4l2_audioout->index = 0;
+ p_v4l2_audioout->capability = 0xbeef0d1c;
+ p_v4l2_audioout->mode = 0xdeadface;
+ ioctl(-1, VIDIOC_S_AUDOUT, p_v4l2_audioout);
+ printf("ioctl(-1, %s, {index=0}) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_S_AUDOUT));
+
/* VIDIOC_LOG_STATUS */
ioctl(-1, VIDIOC_LOG_STATUS, 0);
printf("ioctl(-1, %s) = -1 EBADF (%m)\n",
@@ -1456,6 +1539,42 @@ main(void)
p_v4l2_crop->c.width,
p_v4l2_crop->c.height);
+ /* VIDIOC_ENUMAUDIO */
+ ioctl(-1, VIDIOC_ENUMAUDIO, 0);
+ printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_ENUMAUDIO));
+
+ fill_memory32(p_v4l2_audio, sizeof(*p_v4l2_audio));
+ ioctl(-1, VIDIOC_ENUMAUDIO, p_v4l2_audio);
+ printf("ioctl(-1, %s, {index=%u, reserved=[%#x, %#x]}"
+ ") = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_ENUMAUDIO), p_v4l2_audio->index,
+ p_v4l2_audio->reserved[0], p_v4l2_audio->reserved[1]);
+
+ memset(p_v4l2_audio->reserved, 0, sizeof(p_v4l2_audio->reserved));
+ p_v4l2_audio->index = 0;
+ ioctl(-1, VIDIOC_ENUMAUDIO, p_v4l2_audio);
+ printf("ioctl(-1, %s, {index=0}) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_ENUMAUDIO));
+
+ /* VIDIOC_ENUMAUDOUT */
+ ioctl(-1, VIDIOC_ENUMAUDOUT, 0);
+ printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_ENUMAUDOUT));
+
+ fill_memory32(p_v4l2_audioout, sizeof(*p_v4l2_audioout));
+ ioctl(-1, VIDIOC_ENUMAUDOUT, p_v4l2_audioout);
+ printf("ioctl(-1, %s, {index=%u, reserved=[%#x, %#x]}"
+ ") = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_ENUMAUDOUT), p_v4l2_audioout->index,
+ p_v4l2_audioout->reserved[0], p_v4l2_audioout->reserved[1]);
+
+ memset(p_v4l2_audioout->reserved, 0, sizeof(p_v4l2_audioout->reserved));
+ p_v4l2_audioout->index = 0;
+ ioctl(-1, VIDIOC_ENUMAUDOUT, p_v4l2_audioout);
+ printf("ioctl(-1, %s, {index=0}) = -1 EBADF (%m)\n",
+ XLAT_STR(VIDIOC_ENUMAUDOUT));
+
/* VIDIOC_G_PRIORITY */
ioctl(-1, VIDIOC_G_PRIORITY, 0);
printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n",
diff --git a/v4l2.c b/v4l2.c
index 5984404c1..5c6a05f16 100644
--- a/v4l2.c
+++ b/v4l2.c
@@ -814,6 +814,136 @@ print_v4l2_input(struct tcb *const tcp, const kernel_ulong_t arg)
return RVAL_IOCTL_DECODED;
}
+#include "xlat/v4l2_audio_capabilities.h"
+#include "xlat/v4l2_audio_modes.h"
+
+static int
+print_v4l2_audio(struct tcb *const tcp, const unsigned int code,
+ const kernel_ulong_t arg)
+{
+ struct v4l2_audio a;
+
+ if (entering(tcp))
+ tprints(", ");
+
+ if (entering(tcp) && code != VIDIOC_S_AUDIO) {
+ bool printed = false;
+
+ if (umove_or_printaddr(tcp, arg, &a))
+ return RVAL_IOCTL_DECODED;
+
+ if (code == VIDIOC_ENUMAUDIO) {
+ PRINT_FIELD_U("{", a, index);
+ printed = true;
+ }
+ if (!IS_ARRAY_ZERO(a.reserved)) {
+ PRINT_FIELD_ARRAY(printed ? ", " : "{", a, reserved,
+ tcp, print_xint32_array_member);
+ printed = true;
+ }
+ if (printed)
+ tprints("}");
+
+ set_tcb_priv_ulong(tcp, printed);
+
+ return 0;
+ }
+
+ /* exiting || code == VIDIOC_S_AUDIO */
+ unsigned long printed = exiting(tcp) ? get_tcb_priv_ulong(tcp) : false;
+
+ if ((exiting(tcp) && syserror(tcp)) || umove(tcp, arg, &a)) {
+ if (!printed)
+ printaddr(arg);
+ return RVAL_IOCTL_DECODED;
+ }
+ if (printed)
+ tprints(" => ");
+
+ const char *pfx = "{";
+ if (code != VIDIOC_ENUMAUDIO) {
+ PRINT_FIELD_U(pfx, a, index);
+ pfx = ", ";
+ }
+ if (code != VIDIOC_S_AUDIO) {
+ PRINT_FIELD_CSTRING(pfx, a, name);
+ PRINT_FIELD_FLAGS(", ", a, capability, v4l2_audio_capabilities,
+ "V4L2_AUDCAP_???");
+ pfx = ", ";
+ }
+ PRINT_FIELD_FLAGS(pfx, a, mode, v4l2_audio_modes, "V4L2_AUDMODE_???");
+ if (!IS_ARRAY_ZERO(a.reserved)) {
+ PRINT_FIELD_ARRAY(", ", a, reserved, tcp,
+ print_xint32_array_member);
+ }
+ tprints("}");
+
+ return RVAL_IOCTL_DECODED;
+}
+
+static int
+print_v4l2_audioout(struct tcb *const tcp, const unsigned int code,
+ const kernel_ulong_t arg)
+{
+ struct v4l2_audioout a;
+
+ if (entering(tcp))
+ tprints(", ");
+
+ if (entering(tcp) && code != VIDIOC_S_AUDOUT) {
+ bool printed = false;
+
+ if (umove_or_printaddr(tcp, arg, &a))
+ return RVAL_IOCTL_DECODED;
+
+ if (code == VIDIOC_ENUMAUDOUT) {
+ PRINT_FIELD_U("{", a, index);
+ printed = true;
+ }
+ if (!IS_ARRAY_ZERO(a.reserved)) {
+ PRINT_FIELD_ARRAY(printed ? ", " : "{", a, reserved,
+ tcp, print_xint32_array_member);
+ printed = true;
+ }
+ if (printed)
+ tprints("}");
+
+ set_tcb_priv_ulong(tcp, printed);
+
+ return 0;
+ }
+
+ /* exiting || code == VIDIOC_S_AUDOUT */
+ unsigned long printed = exiting(tcp) ? get_tcb_priv_ulong(tcp) : false;
+
+ if ((exiting(tcp) && syserror(tcp)) || umove(tcp, arg, &a)) {
+ if (!printed)
+ printaddr(arg);
+ return RVAL_IOCTL_DECODED;
+ }
+ if (printed)
+ tprints(" => ");
+
+ const char *pfx = "{";
+ if (code != VIDIOC_ENUMAUDOUT) {
+ PRINT_FIELD_U(pfx, a, index);
+ pfx = ", ";
+ }
+ if (code != VIDIOC_S_AUDOUT) {
+ PRINT_FIELD_CSTRING(pfx, a, name);
+ PRINT_FIELD_X(", ", a, capability);
+ PRINT_FIELD_X(", ", a, mode);
+ pfx = ", ";
+ }
+ if (!IS_ARRAY_ZERO(a.reserved)) {
+ PRINT_FIELD_ARRAY(pfx, a, reserved, tcp,
+ print_xint32_array_member);
+ }
+ tprints("}");
+
+ return RVAL_IOCTL_DECODED;
+}
+
/*
* We include it here and not before print_v4l2_ext_controls as we need
* V4L2_CTRL_CLASS_* definitions for V4L2_CID_*_BASE ones.
@@ -1421,6 +1551,11 @@ MPERS_PRINTER_DECL(int, v4l2_ioctl, struct tcb *const tcp,
case VIDIOC_S_TUNER: /* RW */
return print_v4l2_tuner(tcp, arg, code == VIDIOC_G_TUNER);
+ case VIDIOC_G_AUDIO: /* R */
+ case VIDIOC_S_AUDIO: /* W */
+ case VIDIOC_ENUMAUDIO: /* RW */
+ return print_v4l2_audio(tcp, code, arg);
+
case VIDIOC_QUERYCTRL: /* RW */
return print_v4l2_queryctrl(tcp, arg);
@@ -1441,6 +1576,11 @@ MPERS_PRINTER_DECL(int, v4l2_ioctl, struct tcb *const tcp,
printnum_int(tcp, arg, "%u");
break;
+ case VIDIOC_G_AUDOUT: /* R */
+ case VIDIOC_S_AUDOUT: /* W */
+ case VIDIOC_ENUMAUDOUT: /* RW */
+ return print_v4l2_audioout(tcp, code, arg);
+
case VIDIOC_CROPCAP: /* RW */
return print_v4l2_cropcap(tcp, arg);
diff --git a/xlat/v4l2_audio_capabilities.in b/xlat/v4l2_audio_capabilities.in
new file mode 100644
index 000000000..310df136f
--- /dev/null
+++ b/xlat/v4l2_audio_capabilities.in
@@ -0,0 +1,2 @@
+V4L2_AUDCAP_STEREO 0x1
+V4L2_AUDCAP_AVL 0x2
diff --git a/xlat/v4l2_audio_modes.in b/xlat/v4l2_audio_modes.in
new file mode 100644
index 000000000..5259f8701
--- /dev/null
+++ b/xlat/v4l2_audio_modes.in
@@ -0,0 +1 @@
+V4L2_AUDMODE_AVL 0x1
diff --git a/xlat/v4l2_ioctl_cmds.in b/xlat/v4l2_ioctl_cmds.in
index 74a3d1741..38aaab0af 100644
--- a/xlat/v4l2_ioctl_cmds.in
+++ b/xlat/v4l2_ioctl_cmds.in
@@ -24,8 +24,8 @@ VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
-/* VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio) */
-/* VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) */
+VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
+VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl)
VIDIOC_QUERYMENU _IOWR('V', 37, struct_v4l2_querymenu)
VIDIOC_G_INPUT _IOR ('V', 38, int)
@@ -35,8 +35,8 @@ VIDIOC_S_INPUT _IOWR('V', 39, int)
VIDIOC_G_OUTPUT _IOR ('V', 46, int)
VIDIOC_S_OUTPUT _IOWR('V', 47, int)
/* VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct_v4l2_output) */
-/* VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout) */
-/* VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) */
+VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
+VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
/* VIDIOC_G_MODULATOR _IOWR('V', 54, struct_v4l2_modulator) */
/* VIDIOC_S_MODULATOR _IOW ('V', 55, struct_v4l2_modulator) */
/* VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) */
@@ -48,8 +48,8 @@ VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
/* VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) */
VIDIOC_QUERYSTD _IOR ('V', 63, uint64_t) /* v4l2_std_id */
VIDIOC_TRY_FMT _IOWR('V', 64, struct_v4l2_format)
-/* VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) */
-/* VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) */
+VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio)
+VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout)
VIDIOC_G_PRIORITY _IOR ('V', 67, uint32_t) /* enum v4l2_priority */
VIDIOC_S_PRIORITY _IOW ('V', 68, uint32_t) /* enum v4l2_priority */
/* VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct_v4l2_sliced_vbi_cap) - added in v2.6.16.28-rc1~3732 */