From nobody Sun Aug 9 17:01:41 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hJ4120MM1z6nlwK for ; Sun, 09 Aug 2026 17:01:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hJ4114mmrz3lpZ for ; Sun, 09 Aug 2026 17:01:41 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786294901; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Kv0l52l5XSF5MoTWjwvlqntFQYBN9GhQ+Ji7hfk37Iw=; b=WbD4lRD4oc8g+/ltY7dibgxmLQws4UFnCmL9H09jwaCmpASj6J808tpp2vqh0ryC0XIK+m pxgGsCALTHBulRgIK5SgurNDSex+bl1F9Cx/M1t5zXJkMBEnmW25qHHkHSHnpJJ+gs75i/ hOznn4cIWMkzSI+a87GXsMmOWFhWhQGwEoRfYYbeudUVRH261ZtSlu6CfhUSkkrXTWlZlf JsYXQQyRkwWuth66wQW0LAoTslql9HBqaTdul6jGeJNPr2TQ8BcySYGhG6urDTTNl4tw24 MOMfFEKpfeldspRAPIv7v+0MJIAPYj0PjXK9FaO6LwSoF+UiBoPBdapI1xd6HA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786294901; a=rsa-sha256; cv=none; b=cSqI9N39XiaSNJ1E7G53bEhXiaHw56vo986p5IKJAArWKtGgOoiWUyp2imFgABhLN/jy7x tckzNcdg5ZdLxvAL1IOllJM9ukqM3nmBP6gxUaHmZUGwMtaFodz5iZIrS+wOHKikxmC+0A XaI3iP/Q47fqey7doTNIStzbajuZPJiA+H0Ga+VHSkdULKc+Y47j6Cc5kEqG25imKeJQUn DGj1LOnTwMgI3LTpcpoi2gErLje7fntQ20MhzATxpQu+hHI5QR0cUtYbRTC1W13Ohx50HS oK388zPl9F03QvqbcD6TpZcWe23H/nz4DnFKp3XTZCHXq4iVzk7c68X0kloQHg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786294901; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Kv0l52l5XSF5MoTWjwvlqntFQYBN9GhQ+Ji7hfk37Iw=; b=Z2r6c26PtJHcCR+07GApC2dhVk5hzg5Y7DByujqGO6G+a3tB1VXqdmYDp/JzS5vRFBkrQ5 MH/HmKkzYHqJhWCrcIT8FOcxNCXfEQ0S/VsUhQKeenZ524tr0AD1ICtd3EBDsGRwhtHpi7 XtgE6IFkI7gpQKhhXvBbqCJZ44STF+x2yQOO24gdL9hjrjcfnbrt8chHZm4rwjqkFlsgtV qPOX6fuwsxnAum8xGICfNxZLcbtKy1e1Hl/Jdsitz6b0gN3GY2DzsdNiWhUxE47IveZeUX hR62JKnEhMNCYU68XQAM1a7Eq49cNrYCMyUb194Ksw9ghTYDSq580WDO9hFZLA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hJ4113KW8zXdv for ; Sun, 09 Aug 2026 17:01:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3acc4 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 09 Aug 2026 17:01:41 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Abdelkader Boudih From: Adrian Chadd Subject: git: 5d0258d4ea51 - main - fwcamctl: remove, superseded by the video(4) interface List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: adrian X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5d0258d4ea51738ae28262e01514bb4b78ec158d Auto-Submitted: auto-generated Date: Sun, 09 Aug 2026 17:01:41 +0000 Message-Id: <6a78b275.3acc4.75b8d6d8@gitrepo.freebsd.org> The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=5d0258d4ea51738ae28262e01514bb4b78ec158d commit 5d0258d4ea51738ae28262e01514bb4b78ec158d Author: Abdelkader Boudih AuthorDate: 2026-08-09 16:58:33 +0000 Commit: Adrian Chadd CommitDate: 2026-08-09 16:58:36 +0000 fwcamctl: remove, superseded by the video(4) interface fwcam(4) no longer creates its own character device or implements the FWCAM_* ioctls; it registers with video(4) and is driven through the standard V4L2 interface on /dev/videoN. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D58500 --- sys/dev/firewire/fwcam.h | 80 +------- usr.sbin/Makefile | 1 - usr.sbin/fwcamctl/Makefile | 9 - usr.sbin/fwcamctl/fwcamctl.8 | 156 --------------- usr.sbin/fwcamctl/fwcamctl.c | 450 ------------------------------------------- 5 files changed, 1 insertion(+), 695 deletions(-) diff --git a/sys/dev/firewire/fwcam.h b/sys/dev/firewire/fwcam.h index 4d5ca74e13c5..64ba6d86a04a 100644 --- a/sys/dev/firewire/fwcam.h +++ b/sys/dev/firewire/fwcam.h @@ -135,17 +135,6 @@ * Mode_2: 640x480 YUV411 = 460,800 bytes * Mode_3: 640x480 YUV422 = 614,400 bytes */ -/* - * ioctl interface - */ -struct fwcam_mode { - uint8_t format; /* IIDC video format (0-7) */ - uint8_t mode; /* IIDC video mode (0-7) */ - uint8_t framerate; /* IIDC frame rate (0-7) */ - uint8_t _pad; - uint32_t frame_size; /* computed frame size in bytes (read-only) */ -}; - struct fwcam_feature { uint32_t id; /* FWCAM_FEAT_* */ uint32_t flags; /* FWCAM_FEATF_* (from INQ, read-only) */ @@ -180,54 +169,13 @@ struct fwcam_feature { #define FWCAM_FEATF_AUTO (1 << 2) /* supports auto mode */ #define FWCAM_FEATF_MANUAL (1 << 3) /* supports manual mode */ -struct fwcam_info { - uint32_t formats; /* V_FORMAT_INQ bitmask */ - uint32_t basic_func; /* BASIC_FUNC_INQ */ - uint32_t features_hi; /* FEATURE_HI_INQ */ - uint32_t features_lo; /* FEATURE_LO_INQ */ - uint8_t cur_format; - uint8_t cur_mode; - uint8_t cur_framerate; - uint8_t state; /* FWCAM_STATE_* */ - uint32_t frame_size; - uint32_t frame_dropped; - uint8_t iso_channel; /* active ISO receive channel */ - uint8_t _pad[3]; -}; - -#define FWCAM_GMODE _IOR('C', 1, struct fwcam_mode) -#define FWCAM_SMODE _IOWR('C', 2, struct fwcam_mode) -#define FWCAM_GFEAT _IOWR('C', 3, struct fwcam_feature) -#define FWCAM_SFEAT _IOW('C', 4, struct fwcam_feature) -#define FWCAM_GINFO _IOR('C', 5, struct fwcam_info) - -/* fwcam state values (visible to userland via fwcam_info.state) */ +/* fwcam state values */ #define FWCAM_STATE_IDLE 0 #define FWCAM_STATE_PROBING 1 #define FWCAM_STATE_PROBED 2 #define FWCAM_STATE_STREAMING 3 #define FWCAM_STATE_DETACHING 4 -/* IIDC format/mode/rate/feature/state name tables for userland and driver */ -#define FWCAM_FMT_NMAX 8 -#define FWCAM_RATE_NMAX 8 - -static const char * const fwcam_fmt_names[FWCAM_FMT_NMAX] = { - "VGA (Format_0)", - "Super VGA 1 (Format_1)", - "Super VGA 2 (Format_2)", - "Reserved", - "Reserved", - "Reserved", - "Still Image (Format_6)", - "Partial Image (Format_7)", -}; - -static const char * const fwcam_rate_names[FWCAM_RATE_NMAX] = { - "1.875 fps", "3.75 fps", "7.5 fps", "15 fps", - "30 fps", "60 fps", "120 fps", "240 fps", -}; - static const char * const fwcam_feat_names[FWCAM_FEAT_MAX] = { [FWCAM_FEAT_BRIGHTNESS] = "brightness", [FWCAM_FEAT_AUTO_EXPOSURE] = "auto_exposure", @@ -247,32 +195,6 @@ static const char * const fwcam_feat_names[FWCAM_FEAT_MAX] = { [FWCAM_FEAT_TILT] = "tilt", }; -static const char * const fwcam_state_names[] = { - [FWCAM_STATE_IDLE] = "idle", - [FWCAM_STATE_PROBING] = "probing", - [FWCAM_STATE_PROBED] = "probed", - [FWCAM_STATE_STREAMING] = "streaming", - [FWCAM_STATE_DETACHING] = "detaching", -}; - -/* Format_0 (VGA non-compressed) mode geometry */ -struct fwcam_fmt0_mode { - int w, h; - const char *pixfmt; -}; - -#define FWCAM_FMT0_NMODES 7 - -static const struct fwcam_fmt0_mode fwcam_fmt0_modes[FWCAM_FMT0_NMODES] = { - { 160, 120, "YUV444" }, /* mode 0 */ - { 320, 240, "YUV422" }, /* mode 1 */ - { 640, 480, "YUV411" }, /* mode 2 */ - { 640, 480, "YUV422" }, /* mode 3 */ - { 640, 480, "RGB8" }, /* mode 4 */ - { 640, 480, "Mono8" }, /* mode 5 */ - { 640, 480, "Mono16" }, /* mode 6 */ -}; - /* * Internal constants */ diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index c55592c926a4..9e885d5d45c5 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -27,7 +27,6 @@ SUBDIR= adduser \ extattrctl \ fifolog \ fstyp \ - fwcamctl \ fwcontrol \ fwget \ getfmac \ diff --git a/usr.sbin/fwcamctl/Makefile b/usr.sbin/fwcamctl/Makefile deleted file mode 100644 index 127639c7e91f..000000000000 --- a/usr.sbin/fwcamctl/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -PROG= fwcamctl -SRCS= fwcamctl.c -MAN= fwcamctl.8 -WARNS?= 3 - -SDIR= ${SRCTOP}/sys -CFLAGS+= -I${SDIR} - -.include diff --git a/usr.sbin/fwcamctl/fwcamctl.8 b/usr.sbin/fwcamctl/fwcamctl.8 deleted file mode 100644 index 389117bcc9d0..000000000000 --- a/usr.sbin/fwcamctl/fwcamctl.8 +++ /dev/null @@ -1,156 +0,0 @@ -.\" Copyright (c) 2026 Abdelkader Boudih -.\" -.\" SPDX-License-Identifier: BSD-2-Clause -.\" -.Dd May 27, 2026 -.Dt FWCAMCTL 8 -.Os -.Sh NAME -.Nm fwcamctl -.Nd control utility for IIDC FireWire cameras -.Sh SYNOPSIS -.Nm -.Op Fl f Ar device -.Cm info -.Nm -.Op Fl f Ar device -.Cm snap -.Op Fl o Ar output.ppm -.Op Fl s Ar skip -.Nm -.Op Fl f Ar device -.Cm mode -.Ar format mode rate -.Nm -.Op Fl f Ar device -.Cm feat get -.Ar id -.Nm -.Op Fl f Ar device -.Cm feat set -.Ar id value Op Ar value2 -.Sh DESCRIPTION -The -.Nm -utility controls IIDC 1394-based digital cameras via the -.Xr fwcam 4 -driver. -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl f Ar device -Specify the camera device. -Defaults to -.Pa /dev/fwcam0 . -.El -.Pp -The subcommands are: -.Bl -tag -width indent -.It Cm info -Display camera state, current format/mode/framerate, supported formats, -basic function capabilities, and present features. -.It Cm snap Op Fl o Ar output.ppm Op Fl s Ar skip -Capture a single video frame and write it as a PPM image. -.Pp -.Bl -tag -width indent -compact -.It Fl o Ar output.ppm -Output file path. -Use -.Sq - -for stdout. -Defaults to -.Pa snap.ppm . -.It Fl s Ar skip -Number of frames to skip before capturing, to allow auto-exposure -and auto-white-balance to settle. -Defaults to 5. -.El -.Pp -Supported pixel formats: YUV444, YUV422, YUV411, RGB8, Mono8. -The frame is converted to RGB24 and written as a binary PPM (P6). -.It Cm mode Ar format mode rate -Set the camera video format, mode, and frame rate. -All arguments are integer indices per the IIDC specification. -Only Format_0 (VGA) is currently supported by the -.Xr fwcam 4 -frame assembly path. -.Pp -Format_0 modes: -.Bl -column "Mode" "Resolution" "Pixel format" -compact -.It Em Mode Ta Em Resolution Ta Em Pixel format -.It 0 Ta 160x120 Ta YUV444 -.It 1 Ta 320x240 Ta YUV422 -.It 2 Ta 640x480 Ta YUV411 -.It 3 Ta 640x480 Ta YUV422 -.It 4 Ta 640x480 Ta RGB8 -.It 5 Ta 640x480 Ta Mono8 -.El -.Pp -Frame rates: 0=1.875 1=3.75 2=7.5 3=15 4=30 5=60 fps. -.It Cm feat get Ar id -Query the camera feature with the given numeric ID and display its -inquiry (presence, on/off, auto, manual, range) and current value. -.It Cm feat set Ar id value Op Ar value2 -Set the camera feature with the given numeric ID to -.Ar value . -For the -.Sq white_balance -feature (id 3), -.Ar value -is the U/B component and -.Ar value2 -is the V/R component. -.El -.Pp -Feature IDs: -.Bl -column "ID" "Name" -compact -.It Em ID Ta Em Name -.It 0 Ta brightness -.It 1 Ta auto_exposure -.It 2 Ta sharpness -.It 3 Ta white_balance -.It 4 Ta hue -.It 5 Ta saturation -.It 6 Ta gamma -.It 7 Ta shutter -.It 8 Ta gain -.It 9 Ta iris -.It 10 Ta focus -.It 11 Ta temperature -.It 12 Ta trigger -.It 13 Ta zoom -.It 14 Ta pan -.It 15 Ta tilt -.El -.Sh EXAMPLES -Show camera information: -.Bd -literal -offset indent -fwcamctl info -.Ed -.Pp -Capture a photo to -.Pa photo.ppm , -skipping 10 frames for AE to settle: -.Bd -literal -offset indent -fwcamctl snap -o photo.ppm -s 10 -.Ed -.Pp -Switch to 320x240 YUV422 at 30 fps: -.Bd -literal -offset indent -fwcamctl mode 0 1 4 -.Ed -.Pp -Read the current gain value: -.Bd -literal -offset indent -fwcamctl feat get 8 -.Ed -.Pp -Set brightness to 200: -.Bd -literal -offset indent -fwcamctl feat set 0 200 -.Ed -.Sh SEE ALSO -.Xr fwcam 4 , -.Xr fwcontrol 8 -.Sh AUTHORS -.An Abdelkader Boudih Aq Mt freebsd@seuros.com diff --git a/usr.sbin/fwcamctl/fwcamctl.c b/usr.sbin/fwcamctl/fwcamctl.c deleted file mode 100644 index af484c39dee6..000000000000 --- a/usr.sbin/fwcamctl/fwcamctl.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) 2026 Abdelkader Boudih - * - * SPDX-License-Identifier: BSD-2-Clause - * - * fwcamctl - control utility for fwcam(4) IIDC FireWire cameras - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -static const char *default_dev = "/dev/fwcam0"; - -static void -usage(void) -{ - fprintf(stderr, - "usage: fwcamctl [-f device] info\n" - " fwcamctl [-f device] snap [-o output.ppm] [-s skip]\n" - " fwcamctl [-f device] mode \n" - " fwcamctl [-f device] feat get \n" - " fwcamctl [-f device] feat set [value2]\n" - "\n" - " Feature IDs: 0=brightness 1=auto_exposure 2=sharpness\n" - " 3=white_balance 4=hue 5=saturation 6=gamma\n" - " 7=shutter 8=gain 9=iris 10=focus 11=temperature\n" - " 12=trigger 13=zoom 14=pan 15=tilt\n"); - exit(1); -} - -static inline int -clamp_u8(int v) -{ - if (v < 0) return (0); - if (v > 255) return (255); - return (v); -} - -/* - * IIDC YUV 4:2:2 → RGB24 - * IIDC spec layout: U0 Y0 V0 Y1 (UYVY, 2 pixels per 4 bytes) - */ -static void -yuv422_to_rgb(const uint8_t *src, uint8_t *dst, int w, int h) -{ - int i, n = w * h / 2; - - for (i = 0; i < n; i++) { - int cb = src[0] - 128; - int y0 = src[1]; - int cr = src[2] - 128; - int y1 = src[3]; - src += 4; - - /* pixel 0 */ - dst[0] = clamp_u8(y0 + (int)(1.402f * cr)); - dst[1] = clamp_u8(y0 - (int)(0.34414f * cb) - (int)(0.71414f * cr)); - dst[2] = clamp_u8(y0 + (int)(1.772f * cb)); - /* pixel 1 */ - dst[3] = clamp_u8(y1 + (int)(1.402f * cr)); - dst[4] = clamp_u8(y1 - (int)(0.34414f * cb) - (int)(0.71414f * cr)); - dst[5] = clamp_u8(y1 + (int)(1.772f * cb)); - dst += 6; - } -} - -/* - * IIDC YUV 4:1:1 → RGB24 - * Layout: U0 Y0 Y1 V0 Y2 Y3 (4 pixels per 6 bytes) - */ -static void -yuv411_to_rgb(const uint8_t *src, uint8_t *dst, int w, int h) -{ - int i, j, n = w * h / 4; - - for (i = 0; i < n; i++) { - int cb = src[0] - 128; - int y[4]; - y[0] = src[1]; - y[1] = src[2]; - int cr = src[3] - 128; - y[2] = src[4]; - y[3] = src[5]; - src += 6; - - for (j = 0; j < 4; j++) { - *dst++ = clamp_u8(y[j] + (int)(1.402f * cr)); - *dst++ = clamp_u8(y[j] - (int)(0.34414f * cb) - (int)(0.71414f * cr)); - *dst++ = clamp_u8(y[j] + (int)(1.772f * cb)); - } - } -} - -/* - * IIDC YUV 4:4:4 → RGB24 - * Layout: U Y V (3 bytes/pixel) - */ -static void -yuv444_to_rgb(const uint8_t *src, uint8_t *dst, int w, int h) -{ - int i, n = w * h; - - for (i = 0; i < n; i++) { - int cb = src[0] - 128; - int y = src[1]; - int cr = src[2] - 128; - src += 3; - - *dst++ = clamp_u8(y + (int)(1.402f * cr)); - *dst++ = clamp_u8(y - (int)(0.34414f * cb) - (int)(0.71414f * cr)); - *dst++ = clamp_u8(y + (int)(1.772f * cb)); - } -} - -static int -write_ppm(const char *path, const uint8_t *rgb, int w, int h) -{ - FILE *f; - - if (strcmp(path, "-") == 0) { - f = stdout; - } else { - f = fopen(path, "wb"); - if (f == NULL) { - warn("fopen %s", path); - return (-1); - } - } - - fprintf(f, "P6\n%d %d\n255\n", w, h); - if (fwrite(rgb, 1, (size_t)(w * h * 3), f) != (size_t)(w * h * 3)) { - warn("fwrite"); - if (f != stdout) - fclose(f); - return (-1); - } - - if (f != stdout) - fclose(f); - return (0); -} - -static int -do_snap(int fd, const char *outpath, int skip) -{ - struct fwcam_info info; - uint8_t *frame_buf, *rgb_buf; - uint32_t rgb_size; - ssize_t n; - int w, h, i; - const char *pixfmt; - - if (ioctl(fd, FWCAM_GINFO, &info) < 0) - err(1, "FWCAM_GINFO"); - - if (info.frame_size == 0) - errx(1, "frame_size is 0 — camera not yet probed?"); - - if (info.cur_format != IIDC_FMT_VGA || - info.cur_mode >= nitems(fwcam_fmt0_modes)) - errx(1, "unsupported format %d mode %d for snap " - "(only Format_0 VGA supported)", - info.cur_format, info.cur_mode); - - w = fwcam_fmt0_modes[info.cur_mode].w; - h = fwcam_fmt0_modes[info.cur_mode].h; - pixfmt = fwcam_fmt0_modes[info.cur_mode].pixfmt; - - if (strcmp(pixfmt, "Mono16") == 0) - errx(1, "Mono16 not supported for PPM output"); - - rgb_size = (uint32_t)(w * h * 3); - frame_buf = malloc(info.frame_size); - rgb_buf = malloc(rgb_size); - if (frame_buf == NULL || rgb_buf == NULL) - err(1, "malloc"); - - /* Read frames; skip the first N to let AE/AWB settle */ - for (i = 0; i <= skip; i++) { - n = read(fd, frame_buf, info.frame_size); - if (n < 0) - err(1, "read"); - if ((uint32_t)n < info.frame_size) - errx(1, "short read: got %zd of %u bytes", - n, info.frame_size); - if (i < skip) - fprintf(stderr, "skipping frame %d/%d...\n", i + 1, skip); - } - - /* Convert to RGB24 */ - if (strcmp(pixfmt, "YUV422") == 0) { - yuv422_to_rgb(frame_buf, rgb_buf, w, h); - } else if (strcmp(pixfmt, "YUV411") == 0) { - yuv411_to_rgb(frame_buf, rgb_buf, w, h); - } else if (strcmp(pixfmt, "YUV444") == 0) { - yuv444_to_rgb(frame_buf, rgb_buf, w, h); - } else if (strcmp(pixfmt, "RGB8") == 0) { - memcpy(rgb_buf, frame_buf, rgb_size); - } else if (strcmp(pixfmt, "Mono8") == 0) { - for (i = 0; i < w * h; i++) { - rgb_buf[i * 3 + 0] = frame_buf[i]; - rgb_buf[i * 3 + 1] = frame_buf[i]; - rgb_buf[i * 3 + 2] = frame_buf[i]; - } - } else { - errx(1, "no converter for pixel format %s", pixfmt); - } - - if (write_ppm(outpath, rgb_buf, w, h) < 0) { - free(frame_buf); - free(rgb_buf); - return (1); - } - - fprintf(stderr, "saved %s (%dx%d %s, %u bytes raw)\n", - outpath, w, h, pixfmt, info.frame_size); - - free(frame_buf); - free(rgb_buf); - return (0); -} - -static void -do_info(int fd) -{ - struct fwcam_info info; - int i; - - if (ioctl(fd, FWCAM_GINFO, &info) < 0) - err(1, "FWCAM_GINFO"); - - printf("state: %s\n", - info.state < nitems(fwcam_state_names) ? - fwcam_state_names[info.state] : "unknown"); - printf("cur format: %d (%s)\n", info.cur_format, - info.cur_format < nitems(fwcam_fmt_names) ? - fwcam_fmt_names[info.cur_format] : "?"); - - if (info.cur_format == IIDC_FMT_VGA && - info.cur_mode < nitems(fwcam_fmt0_modes)) { - printf("cur mode: %d (%dx%d %s)\n", info.cur_mode, - fwcam_fmt0_modes[info.cur_mode].w, - fwcam_fmt0_modes[info.cur_mode].h, - fwcam_fmt0_modes[info.cur_mode].pixfmt); - } else { - printf("cur mode: %d\n", info.cur_mode); - } - - printf("cur rate: %d (%s)\n", info.cur_framerate, - info.cur_framerate < nitems(fwcam_rate_names) ? - fwcam_rate_names[info.cur_framerate] : "?"); - printf("iso_channel: %u\n", info.iso_channel); - printf("frame_size: %u bytes\n", info.frame_size); - printf("dropped: %u frames\n", info.frame_dropped); - - printf("formats: 0x%08x (", info.formats); - for (i = 0; i < 8; i++) { - if (info.formats & (1 << (31 - i))) - printf("F%d ", i); - } - printf(")\n"); - - printf("basic_func: 0x%08x", info.basic_func); - if (info.basic_func & IIDC_CAM_POWER_CTRL) printf(" [power_ctrl]"); - if (info.basic_func & IIDC_ONE_SHOT_INQ) printf(" [one_shot]"); - if (info.basic_func & IIDC_MULTI_SHOT_INQ) printf(" [multi_shot]"); - printf("\n"); - - printf("features: hi=0x%08x lo=0x%08x\n", - info.features_hi, info.features_lo); - if (info.features_hi) { - printf(" "); - if (info.features_hi & IIDC_HAS_BRIGHTNESS) printf("brightness "); - if (info.features_hi & IIDC_HAS_AUTO_EXPOSURE) printf("auto_exp "); - if (info.features_hi & IIDC_HAS_SHARPNESS) printf("sharpness "); - if (info.features_hi & IIDC_HAS_WHITE_BALANCE) printf("white_bal "); - if (info.features_hi & IIDC_HAS_HUE) printf("hue "); - if (info.features_hi & IIDC_HAS_SATURATION) printf("saturation "); - if (info.features_hi & IIDC_HAS_GAMMA) printf("gamma "); - if (info.features_hi & IIDC_HAS_SHUTTER) printf("shutter "); - if (info.features_hi & IIDC_HAS_GAIN) printf("gain "); - if (info.features_hi & IIDC_HAS_IRIS) printf("iris "); - if (info.features_hi & IIDC_HAS_FOCUS) printf("focus "); - if (info.features_hi & IIDC_HAS_TEMPERATURE) printf("temperature "); - if (info.features_hi & IIDC_HAS_TRIGGER) printf("trigger "); - printf("\n"); - } -} - -static void -do_mode(int fd, int argc, char **argv) -{ - struct fwcam_mode mode; - - if (argc < 3) - usage(); - - mode.format = (uint8_t)atoi(argv[0]); - mode.mode = (uint8_t)atoi(argv[1]); - mode.framerate = (uint8_t)atoi(argv[2]); - mode.frame_size = 0; - mode._pad = 0; - - if (ioctl(fd, FWCAM_SMODE, &mode) < 0) - err(1, "FWCAM_SMODE"); - - printf("mode set: format=%d mode=%d framerate=%d frame_size=%u\n", - mode.format, mode.mode, mode.framerate, mode.frame_size); -} - -static void -do_feat_get(int fd, int feat_id) -{ - struct fwcam_feature feat; - - if (feat_id < 0 || feat_id >= FWCAM_FEAT_MAX) - errx(1, "invalid feature id %d (0-%d)", feat_id, FWCAM_FEAT_MAX - 1); - - memset(&feat, 0, sizeof(feat)); - feat.id = (uint32_t)feat_id; - - if (ioctl(fd, FWCAM_GFEAT, &feat) < 0) - err(1, "FWCAM_GFEAT"); - - printf("feature %d (%s):\n", feat_id, - fwcam_feat_names[feat_id] != NULL ? fwcam_feat_names[feat_id] : "?"); - printf(" present: %s\n", - (feat.flags & FWCAM_FEATF_PRESENT) ? "yes" : "no"); - printf(" flags: 0x%x", feat.flags); - if (feat.flags & FWCAM_FEATF_ONOFF) printf(" [on/off]"); - if (feat.flags & FWCAM_FEATF_AUTO) printf(" [auto]"); - if (feat.flags & FWCAM_FEATF_MANUAL) printf(" [manual]"); - printf("\n"); - printf(" range: %u - %u\n", feat.min, feat.max); - - if (feat_id == FWCAM_FEAT_WHITE_BALANCE) - printf(" value: U/B=%u V/R=%u\n", feat.value, feat.value2); - else - printf(" value: %u\n", feat.value); -} - -static void -do_feat_set(int fd, int feat_id, uint32_t value, uint32_t value2) -{ - struct fwcam_feature feat; - - if (feat_id < 0 || feat_id >= FWCAM_FEAT_MAX) - errx(1, "invalid feature id %d (0-%d)", feat_id, FWCAM_FEAT_MAX - 1); - - memset(&feat, 0, sizeof(feat)); - feat.id = (uint32_t)feat_id; - feat.value = value; - feat.value2 = value2; - - if (ioctl(fd, FWCAM_SFEAT, &feat) < 0) - err(1, "FWCAM_SFEAT"); - - printf("feature %d (%s) set to %u\n", feat_id, - fwcam_feat_names[feat_id] != NULL ? fwcam_feat_names[feat_id] : "?", value); -} - -int -main(int argc, char *argv[]) -{ - const char *devpath = default_dev; - int fd, ch; - - while ((ch = getopt(argc, argv, "f:")) != -1) { - switch (ch) { - case 'f': - devpath = optarg; - break; - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc < 1) - usage(); - - fd = open(devpath, O_RDWR); - if (fd < 0) - err(1, "open %s", devpath); - - if (strcmp(argv[0], "info") == 0) { - do_info(fd); - - } else if (strcmp(argv[0], "snap") == 0) { - const char *out = "snap.ppm"; - int skip = 5; - - /* re-parse the snap subcommand's own flags */ - optreset = 1; - optind = 1; - while ((ch = getopt(argc, argv, "o:s:")) != -1) { - switch (ch) { - case 'o': - out = optarg; - break; - case 's': - skip = atoi(optarg); - break; - default: - usage(); - } - } - do_snap(fd, out, skip); - - } else if (strcmp(argv[0], "mode") == 0) { - do_mode(fd, argc - 1, argv + 1); - - } else if (strcmp(argv[0], "feat") == 0) { - if (argc < 3) - usage(); - - int feat_id = atoi(argv[2]); - - if (strcmp(argv[1], "get") == 0) { - do_feat_get(fd, feat_id); - } else if (strcmp(argv[1], "set") == 0) { - if (argc < 4) - usage(); - uint32_t val = (uint32_t)atoi(argv[3]); - uint32_t val2 = (argc > 4) ? (uint32_t)atoi(argv[4]) : 0; - do_feat_set(fd, feat_id, val, val2); - } else { - usage(); - } - - } else { - warnx("unknown command: %s", argv[0]); - usage(); - } - - close(fd); - return (0); -}