This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit 81db6810fc74fa8a7a60b5b12525c72bb910c392 Author: zengshuang <[email protected]> AuthorDate: Wed Apr 29 11:11:01 2026 +0800 system/nxcamera: add set/get/query commands for V4L2 controls Add camera control support to nxcamera interactive shell: - set <name> <value>: set a V4L2 control (VIDIOC_S_CTRL) - get <name>: get current control value (VIDIOC_G_CTRL) - query <name>: query control range (VIDIOC_QUERYCTRL) Supported controls: brightness, contrast, saturation, hue, awb, gamma, sharpness, exposure_auto, exposure, focus, focus_auto and zoom. Use the C99 format macros from <inttypes.h> for the int32_t and uint32_t values so the same code builds on both 32-bit and 64-bit hosts. Drop the unused EXTERN wrapper from nxcamera.h, which nxstyle rejects as soon as the header is touched. Signed-off-by: zengshuang <[email protected]> --- include/system/nxcamera.h | 24 +++-- system/nxcamera/nxcamera.c | 40 +++++++++ system/nxcamera/nxcamera_main.c | 192 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+), 5 deletions(-) diff --git a/include/system/nxcamera.h b/include/system/nxcamera.h index 6e102e1ae..4d42dfbfe 100644 --- a/include/system/nxcamera.h +++ b/include/system/nxcamera.h @@ -85,7 +85,7 @@ struct video_msg_s }; /**************************************************************************** - * Public Data + * Public Function Prototypes ****************************************************************************/ #ifdef __cplusplus @@ -93,10 +93,6 @@ extern "C" { #endif -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Name: nxcamera_create * @@ -246,6 +242,24 @@ int nxcamera_setfb(FAR struct nxcamera_s *pcam, FAR const char *device); int nxcamera_setfile(FAR struct nxcamera_s *pcam, FAR const char *pfile, bool isimage); +/**************************************************************************** + * Name: nxcamera_ioctl + * + * Open the capture device, issue an ioctl, and close. + * + * Input Parameters: + * pcam - Pointer to the nxcamera context + * request - ioctl request code + * arg - ioctl argument + * + * Returned Value: + * OK on success, negated errno on failure. + * + ****************************************************************************/ + +int nxcamera_ioctl(FAR struct nxcamera_s *pcam, + int request, unsigned long arg); + #ifdef __cplusplus } #endif diff --git a/system/nxcamera/nxcamera.c b/system/nxcamera/nxcamera.c index 0f74b418a..d2e386995 100644 --- a/system/nxcamera/nxcamera.c +++ b/system/nxcamera/nxcamera.c @@ -866,6 +866,46 @@ err_out: return ret; } +/**************************************************************************** + * Name: nxcamera_ioctl + * + * Open the capture device, issue an ioctl, and close. + * + ****************************************************************************/ + +int nxcamera_ioctl(FAR struct nxcamera_s *pcam, + int request, unsigned long arg) +{ + bool opened = false; + int ret; + int fd; + + fd = pcam->capture_fd; + if (fd < 0) + { + fd = open(pcam->capturedev, O_RDWR); + if (fd < 0) + { + return -errno; + } + + opened = true; + } + + ret = ioctl(fd, request, arg); + if (ret < 0) + { + ret = -errno; + } + + if (opened) + { + close(fd); + } + + return ret; +} + /**************************************************************************** * Name: nxcamera_create * diff --git a/system/nxcamera/nxcamera_main.c b/system/nxcamera/nxcamera_main.c index 013872024..8e56694fe 100644 --- a/system/nxcamera/nxcamera_main.c +++ b/system/nxcamera/nxcamera_main.c @@ -27,7 +27,11 @@ #include <nuttx/config.h> #include <nuttx/video/video.h> +#include <inttypes.h> +#include <sys/ioctl.h> #include <sys/types.h> +#include <sys/video_controls.h> +#include <sys/videoio.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -74,6 +78,9 @@ static int nxcamera_cmd_stream(FAR struct nxcamera_s *pcam, FAR char *parg); static int nxcamera_cmd_input(FAR struct nxcamera_s *pcam, FAR char *parg); static int nxcamera_cmd_output(FAR struct nxcamera_s *pcam, FAR char *parg); static int nxcamera_cmd_stop(FAR struct nxcamera_s *pcam, FAR char *parg); +static int nxcamera_cmd_set(FAR struct nxcamera_s *pcam, FAR char *parg); +static int nxcamera_cmd_get(FAR struct nxcamera_s *pcam, FAR char *parg); +static int nxcamera_cmd_query(FAR struct nxcamera_s *pcam, FAR char *parg); #ifdef CONFIG_NXCAMERA_INCLUDE_HELP static int nxcamera_cmd_help(FAR struct nxcamera_s *pcam, FAR char *parg); #endif @@ -82,6 +89,31 @@ static int nxcamera_cmd_help(FAR struct nxcamera_s *pcam, FAR char *parg); * Private Data ****************************************************************************/ +/* Control name to V4L2 CID mapping */ + +struct nxcamera_ctrl_name_s +{ + FAR const char *name; + uint16_t id; +}; + +static const struct nxcamera_ctrl_name_s g_ctrl_names[] = +{ + { "brightness", V4L2_CID_BRIGHTNESS }, + { "contrast", V4L2_CID_CONTRAST }, + { "saturation", V4L2_CID_SATURATION }, + { "hue", V4L2_CID_HUE }, + { "awb", V4L2_CID_AUTO_WHITE_BALANCE }, + { "gamma", V4L2_CID_GAMMA }, + { "sharpness", V4L2_CID_SHARPNESS }, + { "exposure_auto", V4L2_CID_EXPOSURE_AUTO }, + { "exposure", V4L2_CID_EXPOSURE_ABSOLUTE }, + { "focus", V4L2_CID_FOCUS_ABSOLUTE }, + { "focus_auto", V4L2_CID_FOCUS_AUTO }, + { "zoom", V4L2_CID_ZOOM_ABSOLUTE }, + { NULL, 0 }, +}; + static const struct nxcamera_cmd_s g_nxcamera_cmds[] = { { @@ -96,6 +128,24 @@ static const struct nxcamera_cmd_s g_nxcamera_cmds[] = nxcamera_cmd_output, NXCAMERA_HELP_TEXT("Specify a display device or filename") }, + { + "set", + "name value", + nxcamera_cmd_set, + NXCAMERA_HELP_TEXT("Set a camera control value") + }, + { + "get", + "name", + nxcamera_cmd_get, + NXCAMERA_HELP_TEXT("Get a camera control value") + }, + { + "query", + "name", + nxcamera_cmd_query, + NXCAMERA_HELP_TEXT("Query camera control range") + }, #ifdef CONFIG_NXCAMERA_INCLUDE_HELP { "h", @@ -315,6 +365,148 @@ static int nxcamera_cmd_output(FAR struct nxcamera_s *pcam, FAR char *parg) return ret; } +/**************************************************************************** + * Name: nxcamera_find_ctrl_id + * + * Look up a V4L2 control ID by name. + * + ****************************************************************************/ + +static int nxcamera_find_ctrl_id(FAR const char *name, FAR uint16_t *id) +{ + int i; + + for (i = 0; g_ctrl_names[i].name != NULL; i++) + { + if (strcmp(name, g_ctrl_names[i].name) == 0) + { + *id = g_ctrl_names[i].id; + return OK; + } + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: nxcamera_cmd_set + * + * nxcamera_cmd_set() sets a camera control value. + * Usage: set <name> <value> + * + ****************************************************************************/ + +static int nxcamera_cmd_set(FAR struct nxcamera_s *pcam, FAR char *parg) +{ + struct v4l2_control ctrl; + char name[32]; + int ret; + + if (!parg || sscanf(parg, "%31s %" SCNd32, name, &ctrl.value) < 2) + { + printf("Usage: set <name> <value>\n"); + return -EINVAL; + } + + ret = nxcamera_find_ctrl_id(name, &ctrl.id); + if (ret < 0) + { + printf("Unknown control: %s\n", name); + return ret; + } + + ret = nxcamera_ioctl(pcam, VIDIOC_S_CTRL, (unsigned long)&ctrl); + if (ret < 0) + { + printf("VIDIOC_S_CTRL failed: %d\n", -ret); + } + + return ret; +} + +/**************************************************************************** + * Name: nxcamera_cmd_get + * + * nxcamera_cmd_get() gets a camera control value. + * Usage: get <name> + * + ****************************************************************************/ + +static int nxcamera_cmd_get(FAR struct nxcamera_s *pcam, FAR char *parg) +{ + struct v4l2_control ctrl; + char name[32]; + int ret; + + if (!parg || sscanf(parg, "%31s", name) < 1) + { + printf("Usage: get <name>\n"); + return -EINVAL; + } + + ret = nxcamera_find_ctrl_id(name, &ctrl.id); + if (ret < 0) + { + printf("Unknown control: %s\n", name); + return ret; + } + + ret = nxcamera_ioctl(pcam, VIDIOC_G_CTRL, (unsigned long)&ctrl); + if (ret < 0) + { + printf("VIDIOC_G_CTRL failed: %d\n", -ret); + } + else + { + printf("%s = %" PRId32 "\n", name, ctrl.value); + } + + return ret; +} + +/**************************************************************************** + * Name: nxcamera_cmd_query + * + * nxcamera_cmd_query() queries camera control range info. + * Usage: query <name> + * + ****************************************************************************/ + +static int nxcamera_cmd_query(FAR struct nxcamera_s *pcam, FAR char *parg) +{ + struct v4l2_queryctrl qctrl; + char name[32]; + int ret; + + if (!parg || sscanf(parg, "%31s", name) < 1) + { + printf("Usage: query <name>\n"); + return -EINVAL; + } + + ret = nxcamera_find_ctrl_id(name, &qctrl.id); + if (ret < 0) + { + printf("Unknown control: %s\n", name); + return ret; + } + + ret = nxcamera_ioctl(pcam, VIDIOC_QUERYCTRL, (unsigned long)&qctrl); + if (ret < 0) + { + printf("VIDIOC_QUERYCTRL failed: %d\n", -ret); + } + else + { + printf("%s: min=%" PRId32 " max=%" PRId32 + " step=%" PRIu32 " default=%" PRId32 "\n", + name, qctrl.minimum, qctrl.maximum, + qctrl.step, qctrl.default_value); + } + + return ret; +} + /**************************************************************************** * Name: nxcamera_cmd_quit *
