Video4Linux2 APIを使用しようとしていますが、特定のカメラのさまざまなコントロールを変更するために使用するはずの構造体で奇妙なことが起こっています。何らかの理由で、一部のメンバーが割り当ての変更を報告していません。問題を単純化するために、次のコードを書きました。
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <linux/videodev2.h>
#include <stdlib.h>
#include <errno.h>
#include <stdbool.h>
int setExtendedControl(int id, int value);
int fd = 0;
int main()
{
setExtendedControl(20, 30);
return 0;
}
int setExtendedControl(int id, int value)
{
struct v4l2_ext_control extControl;
struct v4l2_ext_controls extControls;
extControl.id = id;
extControl.value = value;
extControl.value64 = value;
extControl.reserved2[0] = 0;
extControl.reserved2[1] = 0;
extControl.reserved2[2] = 0;
//Put the individual control structure into the
//multi-control container structure and initialize the container
//as well
extControls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
extControls.count = 1;
extControls.controls = &extControl;
printf("extControls.controls = %i, extControl = %i\n", (extControls).controls, &extControl);
extControls.reserved[0] = 0;
extControls.reserved[1] = 0;
extControls.reserved[2] = 0;
extControls.error_idx = 0;
printf("Verifying settings:\n");
printf("extControl.id = %i, id = %i\n", extControl.id, id);
printf("extControl.value = %i, value = %i\n", extControl.value, value);
printf("extControl.value64 = %i, value = %i\n", extControl.value64, value);
printf("extControl.reserved2[0] = %i, set to 0\n", extControl.reserved2[0]);
printf("extControl.reserved2[1] = %i, set to 0\n", extControl.reserved2[1]);
printf("extControl.reserved2[2] = %i, set to 0\n\n", extControl.reserved2[2]);
printf("extControls.ctrl_class = %i, V4L2_CTRL_CLASS_MPEG = %i\n", extControls.ctrl_class,
V4L2_CTRL_CLASS_MPEG);
printf("extControls.count = %i, set to 1\n", extControls.count);
printf("extControls.reserved[0] = %i, set to 0\n", extControls.reserved[0]);
printf("extControls.reserved[1] = %i, set to 0\n", extControls.reserved[1]);
printf("extControls.reserved[2] = %i, set to 0\n", extControls.reserved[2]);
printf("extControls.error_idx = %i, set to 0\n", extControls.error_idx);
printf ("\nRunning secondary check..\n\n");
int rval;
//Set up the individual control structure
//Try to change the control and return the
//value reporting the outcome.
rval = ioctl(fd, VIDIOC_S_EXT_CTRLS, &extControls);
if (extControls.controls != &extControl)
{
printf("\n\nLost the pointer on initial set!\n");
}
//printf("error_idx after initial set %i\n", extControls.error_idx);
//printf("extControl = %i, extControls = %i\n");
//freeStructs(extControl, extControls);
return rval;
}
これを実行すると、「value」および「value64」メンバーが設定されません。以下は、printf の出力です。
extControls.controls = -1954893344, extControl = -1954893344
Verifying settings:
extControl.id = 20, id = 20
extControl.value = 0, value = 30
extControl.value64 = 0, value = 30
extControl.reserved2[0] = 0, set to 0
extControl.reserved2[1] = 0, set to 0
extControl.reserved2[2] = 0, set to 0
extControls.ctrl_class = 10027008, V4L2_CTRL_CLASS_MPEG = 10027008
extControls.count = 1, set to 1
extControls.reserved[0] = 0, set to 0
extControls.reserved[1] = 0, set to 0
extControls.reserved[2] = 0, set to 0
extControls.error_idx = 0, set to 0
そして、ここに gdb からの小さなスニペットがあります:
(gdb) step
printf (__fmt=0x400880 "extControls.controls = %i, extControl = %i\n") at /usr/include/x86_64-linux-gnu/bits/stdio2.h:105
105 return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
(gdb) step
setExtendedControl (id=20, value=30) at ioctlTest.c:30
30 extControl.reserved2[0] = 0;
(gdb) step
Hardware watchpoint 2: extControl
Old value =
{id = 4294960502, size = 32767, reserved2 = {4196309}, {value = 0, value64 = 67750802696962048, string = 0xf0b2ff00000000 <Address 0xf0b2ff00000000 out of bounds>}}
New value =
{id = 20, size = 32767, reserved2 = {0}, {value = 0, value64 = 67750802696962048, string = 0xf0b2ff00000000 <Address 0xf0b2ff00000000 out of bounds>}}
ここでは発生していませんが、このコードのより強力なバージョンでは、extControls.controls のポインター割り当てとメンバー extControl.id の int 割り当ての両方が失敗する他のインスタンスがありました。この性質の構造体メンバー割り当ての失敗の原因は何ですか?
前もって感謝します!