From a6d53ec6938b64816cbbc8df7156cea4b611afb5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 25 Feb 2007 11:04:24 +0100 Subject: cx23416 doc updates + rename CX2341X_ENC_UNKNOWN From: Hans Verkuil The documentation of Several miscellaneous commands was updated. As a result of which the CX2341X_ENC_UNKNOWN command was renamed to CX2341X_ENC_SET_VERT_CROP_LINE. Signed-off-by: Hans Verkuil --- .../video4linux/cx2341x/fw-encoder-api.txt | 19 ++++++++++--------- linux/include/media/cx2341x.h | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/linux/Documentation/video4linux/cx2341x/fw-encoder-api.txt b/linux/Documentation/video4linux/cx2341x/fw-encoder-api.txt index 242104ce5..5dd3109a8 100644 --- a/linux/Documentation/video4linux/cx2341x/fw-encoder-api.txt +++ b/linux/Documentation/video4linux/cx2341x/fw-encoder-api.txt @@ -663,12 +663,13 @@ Param[0] ------------------------------------------------------------------------------- -Name CX2341X_ENC_UNKNOWN +Name CX2341X_ENC_SET_VERT_CROP_LINE Enum 219/0xDB Description - Unknown API, it's used by Hauppauge though. + Something to do with 'Vertical Crop Line' Param[0] - 0 This is the value Hauppauge uses, Unknown what it means. + If saa7114 and raw VBI capture and 60 Hz, then set to 10001. + Else 0. ------------------------------------------------------------------------------- @@ -682,11 +683,9 @@ Param[0] Command number: 1=set initial SCR value when starting encoding (works). 2=set quality mode (apparently some test setting). - 3=setup advanced VIM protection handling (supposedly only for the cx23416 - for raw YUV). - Actually it looks like this should be 0 for saa7114/5 based card and 1 - for cx25840 based cards. - 4=generate artificial PTS timestamps + 3=setup advanced VIM protection handling. + Always 1 for the cx23416 and 0 for cx23415. + 4=generate DVD compatible PTS timestamps 5=USB flush mode 6=something to do with the quantization matrix 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2) @@ -698,7 +697,9 @@ Param[0] 9=set history parameters of the video input module 10=set input field order of VIM 11=set quantization matrix - 12=reset audio interface + 12=reset audio interface after channel change or input switch (has no argument). + Needed for the cx2584x, not needed for the mspx4xx, but it doesn't seem to + do any harm calling it regardless. 13=set audio volume delay 14=set audio delay diff --git a/linux/include/media/cx2341x.h b/linux/include/media/cx2341x.h index 583b0621f..38c12fed7 100644 --- a/linux/include/media/cx2341x.h +++ b/linux/include/media/cx2341x.h @@ -166,7 +166,7 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix); #define CX2341X_ENC_SET_PLACEHOLDER 0xd7 #define CX2341X_ENC_MUTE_VIDEO 0xd9 #define CX2341X_ENC_MUTE_AUDIO 0xda -#define CX2341X_ENC_UNKNOWN 0xdb +#define CX2341X_ENC_SET_VERT_CROP_LINE 0xdb #define CX2341X_ENC_MISC 0xdc /* OSD API, specific to the cx23415 */ -- cgit v1.2.3 From 3456dcb8bdd105f85c8f1a177d03051f698da268 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 25 Feb 2007 11:06:58 +0100 Subject: Incremented DVB_API_VERSION_MINOR. From: Hans Verkuil DVB_API_VERSION_MINOR was incremented to reflect the video.h/audio.h additions that were needed to support the cx23415. Signed-off-by: Hans Verkuil CC: Johannes Stezenbach --- linux/include/linux/dvb/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/include/linux/dvb/version.h b/linux/include/linux/dvb/version.h index 6183c9c48..126e0c26c 100644 --- a/linux/include/linux/dvb/version.h +++ b/linux/include/linux/dvb/version.h @@ -24,6 +24,6 @@ #define _DVBVERSION_H_ #define DVB_API_VERSION 3 -#define DVB_API_VERSION_MINOR 1 +#define DVB_API_VERSION_MINOR 2 #endif /*_DVBVERSION_H_*/ -- cgit v1.2.3 From 0ef39045d22cd86b1faf31910298a61ad9e9e4b7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 25 Feb 2007 11:13:08 +0100 Subject: Remove V4L2_CHIP_MATCH_ALWAYS. From: Hans Verkuil V4L2_CHIP_MATCH_ALWAYS turned out to be confusing and also unnecessary. It's now removed. Signed-off-by: Hans Verkuil --- linux/drivers/media/video/cafe_ccic.c | 3 ++- linux/drivers/media/video/v4l2-common.c | 4 ---- linux/include/linux/videodev2.h | 7 +++---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c index 5f35836ad..b96d45654 100644 --- a/linux/drivers/media/video/cafe_ccic.c +++ b/linux/drivers/media/video/cafe_ccic.c @@ -826,7 +826,7 @@ static int __cafe_cam_reset(struct cafe_camera *cam) */ static int cafe_cam_init(struct cafe_camera *cam) { - struct v4l2_chip_ident chip = { V4L2_CHIP_MATCH_ALWAYS }; + struct v4l2_chip_ident chip = { V4L2_CHIP_MATCH_I2C_ADDR, 0, 0, 0 }; int ret; mutex_lock(&cam->s_mutex); @@ -836,6 +836,7 @@ static int cafe_cam_init(struct cafe_camera *cam) ret = __cafe_cam_reset(cam); if (ret) goto out; + chip.match_chip = cam->sensor->addr; ret = __cafe_cam_cmd(cam, VIDIOC_G_CHIP_IDENT, &chip); if (ret) goto out; diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index b2d57d888..60c56a8b0 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -1596,8 +1596,6 @@ u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id) int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip) { switch (match_type) { - case V4L2_CHIP_MATCH_ALWAYS: - return 1; case V4L2_CHIP_MATCH_I2C_DRIVER: return (c != NULL && c->driver != NULL && c->driver->id == match_chip); case V4L2_CHIP_MATCH_I2C_ADDR: @@ -1610,8 +1608,6 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_c int v4l2_chip_match_host(u32 match_type, u32 match_chip) { switch (match_type) { - case V4L2_CHIP_MATCH_ALWAYS: - return 1; case V4L2_CHIP_MATCH_HOST: return match_chip == 0; default: diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 8a5aabb84..76af1e16a 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -1387,10 +1387,9 @@ struct v4l2_streamparm /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ -#define V4L2_CHIP_MATCH_ALWAYS 0 /* Match always (match_chip is not used) */ -#define V4L2_CHIP_MATCH_HOST 1 /* Match against chip ID on host (0 for the host) */ -#define V4L2_CHIP_MATCH_I2C_DRIVER 2 /* Match against I2C driver ID */ -#define V4L2_CHIP_MATCH_I2C_ADDR 3 /* Match against I2C 7-bit address */ +#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ +#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver ID */ +#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ struct v4l2_register { __u32 match_type; /* Match type */ -- cgit v1.2.3 From 2f4a95341278526ea6b771fbf584c7fa4c631cfa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 25 Feb 2007 11:17:04 +0100 Subject: Add v4l2-ctl support for output overlays and framebuffer ioctls. From: Hans Verkuil Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-ctl.cpp | 248 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 228 insertions(+), 20 deletions(-) diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 11af185f7..c466b4b63 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -1,8 +1,9 @@ /* Copyright (C) 2003-2004 Kevin Thayer - Cleanup and VBI and audio in/out options: - Copyright (C) 2004 Hans Verkuil + Cleanup and VBI and audio in/out options, introduction in v4l-dvb, + support for most new APIs since 2006. + Copyright (C) 2004, 2006, 2007 Hans Verkuil This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -79,6 +80,8 @@ enum Option { OptSetSlicedVbiOutFormat, OptGetOverlayFormat, //OptSetOverlayFormat, TODO + OptGetOutputOverlayFormat, + OptSetOutputOverlayFormat, OptGetVbiFormat, //OptSetVbiFormat, TODO OptGetVbiOutFormat, @@ -94,6 +97,8 @@ enum Option { OptSetVideoOutFormat, OptGetSlicedVbiCap, OptGetSlicedVbiOutCap, + OptGetFBuf, + OptSetFBuf, OptGetVideoCrop, OptSetVideoCrop, OptGetAudioInput, @@ -107,6 +112,8 @@ enum Option { static char options[OptLast]; +static unsigned capabilities; + typedef std::vector ctrl_list; static ctrl_list user_ctrls; static ctrl_list mpeg_ctrls; @@ -136,8 +143,12 @@ static const flag_def service_def[] = { }; /* fmts specified */ -#define FMTWidth (1L<<0) -#define FMTHeight (1L<<1) +#define FmtTop (1L<<0) +#define FmtLeft (1L<<1) +#define FmtWidth (1L<<2) +#define FmtHeight (1L<<3) +#define FmtChromaKey (1L<<4) +#define FmtGlobalAlpha (1L<<5) /* crop specified */ #define CropWidth (1L<<0) @@ -183,6 +194,8 @@ static struct option long_options[] = { {"verbose", no_argument, 0, OptVerbose}, {"log-status", no_argument, 0, OptLogStatus}, {"get-fmt-overlay", no_argument, 0, OptGetOverlayFormat}, + {"get-fmt-output-overlay", no_argument, 0, OptGetOutputOverlayFormat}, + {"set-fmt-output-overlay", required_argument, 0, OptSetOutputOverlayFormat}, {"get-fmt-sliced-vbi", no_argument, 0, OptGetSlicedVbiFormat}, {"set-fmt-sliced-vbi", required_argument, 0, OptSetSlicedVbiFormat}, {"get-fmt-sliced-vbi-out", no_argument, 0, OptGetSlicedVbiOutFormat}, @@ -191,6 +204,8 @@ static struct option long_options[] = { {"get-fmt-vbi-out", no_argument, 0, OptGetVbiOutFormat}, {"get-sliced-vbi-cap", no_argument, 0, OptGetSlicedVbiCap}, {"get-sliced-vbi-out-cap", no_argument, 0, OptGetSlicedVbiOutCap}, + {"get-fbuf", no_argument, 0, OptGetFBuf}, + {"set-fbuf", required_argument, 0, OptSetFBuf}, {"get-crop-video", no_argument, 0, OptGetVideoCrop}, {"set-crop-video", required_argument, 0, OptSetVideoCrop}, {0, 0, 0, 0} @@ -253,17 +268,21 @@ static void usage(void) printf(" --list-formats display supported video formats [VIDIOC_ENUM_FMT]\n"); printf(" -V, --get-fmt-video\n"); printf(" query the video capture format [VIDIOC_G_FMT]\n"); - printf(" -v, --set-fmt-video=width=,height=\n"); + printf(" -v, --set-fmt-video=width=,height=\n"); printf(" set the video capture format [VIDIOC_S_FMT]\n"); printf(" --verbose turn on verbose ioctl error reporting.\n"); printf("\n"); printf("Uncommon options:\n"); printf(" --get-fmt-video-out\n"); printf(" query the video output format [VIDIOC_G_FMT]\n"); - printf(" --set-fmt-video-out=width=,height=\n"); + printf(" --set-fmt-video-out=left=,top=,width=,height=\n"); printf(" set the video output format [VIDIOC_S_FMT]\n"); printf(" --get-fmt-overlay\n"); printf(" query the video overlay format [VIDIOC_G_FMT]\n"); + printf(" --get-fmt-output-overlay\n"); + printf(" query the video output overlay format [VIDIOC_G_FMT]\n"); + printf(" --set-fmt-output-overlay=chromakey=,global_alpha=\n"); + printf(" set the video output overlay format [VIDIOC_S_FMT]\n"); printf(" --get-sliced-vbi-cap\n"); printf(" query the sliced VBI capture capabilities [VIDIOC_G_SLICED_VBI_CAP]\n"); printf(" --get-sliced-vbi-out-cap\n"); @@ -280,6 +299,9 @@ static void usage(void) printf(" vps: VPS (PAL/SECAM)\n"); printf(" --get-fmt-vbi query the VBI capture format [VIDIOC_G_FMT]\n"); printf(" --get-fmt-vbi-out query the VBI output format [VIDIOC_G_FMT]\n"); + printf(" --get-fbuf query the overlay framebuffer data [VIDIOC_G_FBUF]\n"); + printf(" --set-fbuf=chromakey=<0/1>,global_alpha=<0/1>,local_alpha=<0/1>\n"); + printf(" set the overlay framebuffer [VIDIOC_S_FBUF]\n"); printf(" --get-crop-video\n"); printf(" query the video capture crop window [VIDIOC_G_CROP]\n"); printf(" --set-crop-video=top=,left=,width=,height=\n"); @@ -327,6 +349,8 @@ static std::string buftype2s(int type) return "Sliced VBI Capture"; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: return "Sliced VBI Output"; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + return "Video Output Overlay"; case V4L2_BUF_TYPE_PRIVATE: return "Private"; default: @@ -364,6 +388,10 @@ static std::string field2s(int val) return "Sequential Bottom-Top"; case V4L2_FIELD_ALTERNATE: return "Alternating"; + case V4L2_FIELD_INTERLACED_TB: + return "Interlaced Top-Bottom"; + case V4L2_FIELD_INTERLACED_BT: + return "Interlaced Bottom-Top"; default: return "Unknown (" + num2s(val) + ")"; } @@ -575,6 +603,62 @@ static void find_controls(int fd) } } +static std::string fbufcap2s(unsigned cap) +{ + std::string s; + + if (cap & V4L2_FBUF_CAP_EXTERNOVERLAY) + s += "\t\tExtern Overlay\n"; + if (cap & V4L2_FBUF_CAP_CHROMAKEY) + s += "\t\tChromakey\n"; + if (cap & V4L2_FBUF_CAP_GLOBAL_ALPHA) + s += "\t\tGlobal Alpha\n"; + if (cap & V4L2_FBUF_CAP_LOCAL_ALPHA) + s += "\t\tLocal Alpha\n"; + if (cap & V4L2_FBUF_CAP_LIST_CLIPPING) + s += "\t\tClipping List\n"; + if (cap & V4L2_FBUF_CAP_BITMAP_CLIPPING) + s += "\t\tClipping Bitmap\n"; + if (s.empty()) s += "\t\t\n"; + return s; +} + +static std::string fbufflags2s(unsigned fl) +{ + std::string s; + + if (fl & V4L2_FBUF_FLAG_PRIMARY) + s += "\t\tPrimary Graphics Surface\n"; + if (fl & V4L2_FBUF_FLAG_OVERLAY) + s += "\t\tOverlay Matches Capture/Output Size\n"; + if (fl & V4L2_FBUF_FLAG_CHROMAKEY) + s += "\t\tChromakey\n"; + if (fl & V4L2_FBUF_FLAG_GLOBAL_ALPHA) + s += "\t\tGlobal Alpha\n"; + if (fl & V4L2_FBUF_FLAG_LOCAL_ALPHA) + s += "\t\tLocal Alpha\n"; + if (s.empty()) s += "\t\t\n"; + return s; +} + +static void printfbuf(const struct v4l2_framebuffer &fb) +{ + int is_ext = fb.capability & V4L2_FBUF_CAP_EXTERNOVERLAY; + + printf("Capability : %s", fbufcap2s(fb.capability).c_str() + 2); + printf("Flags : %s", fbufflags2s(fb.flags).c_str() + 2); + printf("Width : %d\n", fb.fmt.width); + printf("Height : %d\n", fb.fmt.height); + printf("Pixel Format : %s\n", fcc2s(fb.fmt.pixelformat).c_str()); + if (!is_ext) { + printf("Bytes per Line: %d\n", fb.fmt.bytesperline); + printf("Size image : %d\n", fb.fmt.sizeimage); + printf("Colorspace : %s\n", colorspace2s(fb.fmt.colorspace).c_str()); + if (fb.fmt.priv) + printf("Custom Info : %08x\n", fb.fmt.priv); + } +} + static void printcrop(const struct v4l2_crop &crop) { printf("Crop: Left %d, Top %d, Width %d, Height %d\n", @@ -600,9 +684,15 @@ static int printfmt(struct v4l2_format vfmt) printf("\tBytes per Line: %u\n", vfmt.fmt.pix.bytesperline); printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage); printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix.colorspace).c_str()); + if (vfmt.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + (capabilities & V4L2_CAP_VIDEO_OUTPUT_POS)) { + printf("\tLeft/Top : %d/%d\n", + vfmt.fmt.pix.left, vfmt.fmt.pix.top); + } if (vfmt.fmt.pix.priv) printf("\tCustom Info : %08x\n", vfmt.fmt.pix.priv); break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: case V4L2_BUF_TYPE_VIDEO_OVERLAY: printf("\tType : %s\n", buftype2s(vfmt.type).c_str()); printf("\tLeft/Top : %d/%d\n", @@ -610,9 +700,10 @@ static int printfmt(struct v4l2_format vfmt) printf("\tWidth/Height: %d/%d\n", vfmt.fmt.win.w.width, vfmt.fmt.win.w.height); printf("\tField : %s\n", field2s(vfmt.fmt.win.field).c_str()); - // TODO: check G_FBUF capabilities - printf("\tChroma Key : %08x\n", vfmt.fmt.win.chromakey); + printf("\tChroma Key : 0x%08x\n", vfmt.fmt.win.chromakey); + printf("\tGlobal Alpha: 0x%02x\n", vfmt.fmt.win.global_alpha); printf("\tClip Count : %u\n", vfmt.fmt.win.clipcount); + printf("\tClip Bitmap : %s\n", vfmt.fmt.win.bitmap ? "Yes" : "No"); break; case V4L2_BUF_TYPE_VBI_CAPTURE: case V4L2_BUF_TYPE_VBI_OUTPUT: @@ -752,6 +843,8 @@ static std::string cap2s(unsigned cap) s += "\t\tVideo Output\n"; if (cap & V4L2_CAP_VIDEO_OVERLAY) s += "\t\tVideo Overlay\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) + s += "\t\tVideo Output Overlay\n"; if (cap & V4L2_CAP_VBI_CAPTURE) s += "\t\tVBI Capture\n"; if (cap & V4L2_CAP_VBI_OUTPUT) @@ -762,6 +855,8 @@ static std::string cap2s(unsigned cap) s += "\t\tSliced VBI Output\n"; if (cap & V4L2_CAP_RDS_CAPTURE) s += "\t\tRDS Capture\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT_POS) + s += "\t\tVideo Output Position\n"; if (cap & V4L2_CAP_TUNER) s += "\t\tTuner\n"; if (cap & V4L2_CAP_AUDIO) @@ -942,6 +1037,8 @@ int main(int argc, char **argv) unsigned int set_fmts = 0; unsigned int set_fmts_out = 0; unsigned int set_crop = 0; + unsigned int set_fbuf = 0; + unsigned int set_overlay_fmt_out = 0; int mode = V4L2_TUNER_MODE_STEREO; /* set audio mode */ @@ -954,6 +1051,7 @@ int main(int argc, char **argv) struct v4l2_format vbi_fmt_out; /* set_format/get_format for sliced VBI output */ struct v4l2_format raw_fmt; /* set_format/get_format for VBI */ struct v4l2_format raw_fmt_out; /* set_format/get_format for VBI output */ + struct v4l2_format overlay_fmt_out; /* set_format/get_format video overlay output */ struct v4l2_tuner tuner; /* set_tuner/get_tuner */ struct v4l2_capability vcap; /* list_cap */ struct v4l2_input vin; /* list_inputs */ @@ -961,6 +1059,7 @@ int main(int argc, char **argv) struct v4l2_audio vaudio; /* list audio inputs */ struct v4l2_audioout vaudout; /* audio outputs */ struct v4l2_rect vcrop; /* crop rect */ + struct v4l2_framebuffer fbuf; /* fbuf */ int input; /* set_input/get_input */ int output; /* set_output/get_output */ v4l2_std_id std; /* get_std/set_std */ @@ -975,6 +1074,7 @@ int main(int argc, char **argv) memset(&raw_fmt, 0, sizeof(raw_fmt)); memset(&vfmt_out, 0, sizeof(vfmt_out)); memset(&vbi_fmt_out, 0, sizeof(vbi_fmt_out)); + memset(&overlay_fmt_out, 0, sizeof(overlay_fmt_out)); memset(&raw_fmt_out, 0, sizeof(raw_fmt_out)); memset(&tuner, 0, sizeof(tuner)); memset(&vcap, 0, sizeof(vcap)); @@ -985,6 +1085,7 @@ int main(int argc, char **argv) memset(&vcrop, 0, sizeof(vcrop)); memset(&vf, 0, sizeof(vf)); memset(&vs, 0, sizeof(vs)); + memset(&fbuf, 0, sizeof(fbuf)); if (argc == 1) { usage(); @@ -1031,11 +1132,11 @@ int main(int argc, char **argv) switch (parse_subopt(&subs, subopts, &value)) { case 0: vfmt.fmt.pix.width = strtol(value, 0L, 0); - set_fmts |= FMTWidth; + set_fmts |= FmtWidth; break; case 1: vfmt.fmt.pix.height = strtol(value, 0L, 0); - set_fmts |= FMTHeight; + set_fmts |= FmtHeight; break; } } @@ -1044,6 +1145,8 @@ int main(int argc, char **argv) subs = optarg; while (*subs != '\0') { static char *const subopts[] = { + "top", + "left", "width", "height", NULL @@ -1051,12 +1154,67 @@ int main(int argc, char **argv) switch (parse_subopt(&subs, subopts, &value)) { case 0: - vfmt_out.fmt.pix.width = strtol(value, 0L, 0); - set_fmts_out |= FMTWidth; + vfmt_out.fmt.pix.top = strtol(value, 0L, 0); + set_fmts_out |= FmtTop; break; case 1: + vfmt_out.fmt.pix.left = strtol(value, 0L, 0); + set_fmts_out |= FmtLeft; + break; + case 2: + vfmt_out.fmt.pix.width = strtol(value, 0L, 0); + set_fmts_out |= FmtWidth; + break; + case 3: vfmt_out.fmt.pix.height = strtol(value, 0L, 0); - set_fmts_out |= FMTHeight; + set_fmts_out |= FmtHeight; + break; + } + } + break; + case OptSetOutputOverlayFormat: + subs = optarg; + while (*subs != '\0') { + static char *const subopts[] = { + "chromakey", + "global_alpha", + NULL + }; + + switch (parse_subopt(&subs, subopts, &value)) { + case 0: + overlay_fmt_out.fmt.win.chromakey = strtol(value, 0L, 0); + set_overlay_fmt_out |= FmtChromaKey; + break; + case 1: + overlay_fmt_out.fmt.win.global_alpha = strtol(value, 0L, 0); + set_overlay_fmt_out |= FmtGlobalAlpha; + break; + } + } + break; + case OptSetFBuf: + subs = optarg; + while (*subs != '\0') { + static char *const subopts[] = { + "chromakey", + "global_alpha", + "local_alpha", + NULL + }; + + switch (parse_subopt(&subs, subopts, &value)) { + case 0: + fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_CHROMAKEY : 0; + set_fbuf |= V4L2_FBUF_FLAG_CHROMAKEY; + break; + case 1: + fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_GLOBAL_ALPHA : 0; + set_fbuf |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; + break; + case 2: + fbuf.flags |= strtol(value, 0L, 0) ? V4L2_FBUF_FLAG_LOCAL_ALPHA : 0; + set_fbuf |= V4L2_FBUF_FLAG_LOCAL_ALPHA; break; } } @@ -1251,6 +1409,7 @@ int main(int argc, char **argv) free(device); doioctl(fd, VIDIOC_QUERYCAP, &vcap, "VIDIOC_QUERYCAP"); + capabilities = vcap.capabilities; find_controls(fd); for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) { if (ctrl_str2id.find(*iter) == ctrl_str2id.end()) { @@ -1278,10 +1437,12 @@ int main(int argc, char **argv) options[OptGetFreq] = 1; options[OptGetTuner] = 1; options[OptGetOverlayFormat] = 1; + options[OptGetOutputOverlayFormat] = 1; options[OptGetVbiFormat] = 1; options[OptGetVbiOutFormat] = 1; options[OptGetSlicedVbiFormat] = 1; options[OptGetSlicedVbiOutFormat] = 1; + options[OptGetFBuf] = 1; } /* Information Opts */ @@ -1373,9 +1534,9 @@ int main(int argc, char **argv) if (ioctl(fd, VIDIOC_G_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n"); else { - if (set_fmts & FMTWidth) + if (set_fmts & FmtWidth) in_vfmt.fmt.pix.width = vfmt.fmt.pix.width; - if (set_fmts & FMTHeight) + if (set_fmts & FmtHeight) in_vfmt.fmt.pix.height = vfmt.fmt.pix.height; if (ioctl(fd, VIDIOC_S_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_S_FMT failed\n"); @@ -1389,10 +1550,14 @@ int main(int argc, char **argv) if (ioctl(fd, VIDIOC_G_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n"); else { - if (set_fmts & FMTWidth) - in_vfmt.fmt.pix.width = vfmt.fmt.pix.width; - if (set_fmts & FMTHeight) - in_vfmt.fmt.pix.height = vfmt.fmt.pix.height; + if (set_fmts_out & FmtTop) + in_vfmt.fmt.pix.top = vfmt_out.fmt.pix.top; + if (set_fmts_out & FmtLeft) + in_vfmt.fmt.pix.left = vfmt_out.fmt.pix.left; + if (set_fmts_out & FmtWidth) + in_vfmt.fmt.pix.width = vfmt_out.fmt.pix.width; + if (set_fmts_out & FmtHeight) + in_vfmt.fmt.pix.height = vfmt_out.fmt.pix.height; if (ioctl(fd, VIDIOC_S_FMT, &in_vfmt) < 0) fprintf(stderr, "ioctl: VIDIOC_S_FMT failed\n"); } @@ -1422,9 +1587,37 @@ int main(int argc, char **argv) } } + if (options[OptSetOutputOverlayFormat]) { + struct v4l2_format fmt; + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY; + if (ioctl(fd, VIDIOC_G_FMT, &fmt, "VIDIOC_G_FMT") < 0) + fprintf(stderr, "ioctl: VIDIOC_G_FMT failed\n"); + else { + if (set_overlay_fmt_out & FmtChromaKey) + fmt.fmt.win.chromakey = overlay_fmt_out.fmt.win.chromakey; + if (set_overlay_fmt_out & FmtGlobalAlpha) + fmt.fmt.win.global_alpha = overlay_fmt_out.fmt.win.global_alpha; + if (ioctl(fd, VIDIOC_S_FMT, &fmt, "VIDIOC_S_FMT") < 0) + fprintf(stderr, "ioctl: VIDIOC_S_FMT failed\n"); + } + } + + if (options[OptSetFBuf]) { + struct v4l2_framebuffer fb; + if (ioctl(fd, VIDIOC_G_FBUF, &fb, "VIDIOC_G_FBUF") < 0) + fprintf(stderr, "ioctl: VIDIOC_G_FBUF failed\n"); + else { + fb.flags &= ~set_fbuf; + fb.flags |= fbuf.flags; + if (ioctl(fd, VIDIOC_S_FBUF, &fb) < 0) + fprintf(stderr, "ioctl: VIDIOC_S_FBUF failed\n"); + } + } + if (options[OptSetVideoCrop]) { struct v4l2_crop in_crop; - printf("ioctl: VIDIOC_S_CROP\n"); + in_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd, VIDIOC_G_CROP, &in_crop) < 0) fprintf(stderr, "ioctl: VIDIOC_G_CROP failed\n"); @@ -1510,6 +1703,15 @@ int main(int argc, char **argv) fprintf(stderr, "error printing result\n"); } + if (options[OptGetOutputOverlayFormat]) { + struct v4l2_format fmt; + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY; + if (doioctl(fd, VIDIOC_G_FMT, &fmt, "VIDIOC_G_FMT") == 0) + if (printfmt(fmt) != 0) + fprintf(stderr, "error printing result\n"); + } + if (options[OptGetSlicedVbiFormat]) { vbi_fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; if (doioctl(fd, VIDIOC_G_FMT, &vbi_fmt, @@ -1546,6 +1748,12 @@ int main(int argc, char **argv) "error printing result\n"); } + if (options[OptGetFBuf]) { + struct v4l2_framebuffer fb; + if (doioctl(fd, VIDIOC_G_FBUF, &fb, "VIDIOC_G_FBUF") == 0) + printfbuf(fb); + } + if (options[OptGetVideoCrop]) { struct v4l2_crop crop; -- cgit v1.2.3 From a352e034d40183ad3248233b75352a71f698771c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 25 Feb 2007 11:20:58 +0100 Subject: Add v4l2-dbg debugging utility. From: Hans Verkuil With v4l2-dbg it is possible to make register dumps of host or i2c chips. It is also possible to query what chips are available. This is just the first version, it will be improved substantially. Signed-off-by: Hans Verkuil --- v4l2-apps/util/Makefile | 2 +- v4l2-apps/util/v4l2-dbg.cpp | 516 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 v4l2-apps/util/v4l2-dbg.cpp diff --git a/v4l2-apps/util/Makefile b/v4l2-apps/util/Makefile index 06452b0ae..f13773c70 100644 --- a/v4l2-apps/util/Makefile +++ b/v4l2-apps/util/Makefile @@ -2,7 +2,7 @@ CPPFLAGS += -I../../linux/include -binaries = v4l2-ctl +binaries = v4l2-ctl v4l2-dbg .PHONY: all clean install qv4l2 diff --git a/v4l2-apps/util/v4l2-dbg.cpp b/v4l2-apps/util/v4l2-dbg.cpp new file mode 100644 index 000000000..70d465dea --- /dev/null +++ b/v4l2-apps/util/v4l2-dbg.cpp @@ -0,0 +1,516 @@ +/* + Copyright (C) 2007 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include /* Uses _GNU_SOURCE to define getsubopt in stdlib.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +/* Short option list + + Please keep in alphabetical order. + That makes it easier to see which short options are still free. + + In general the lower case is used to set something and the upper + case is used to retrieve a setting. */ +enum Option { + OptListRegisters = 'R', + OptSetRegister = 'r', + OptSetSlicedVbiFormat = 'b', + OptSetDevice = 'd', + OptGetDriverInfo = 'D', + OptListChipIdents = 'C', + OptGetChipIdent = 'c', + OptHelp = 'h', + + OptLogStatus = 128, + OptVerbose, + OptLast = 256 +}; + +static char options[OptLast]; + +static unsigned capabilities; + +static struct option long_options[] = { + {"device", required_argument, 0, OptSetDevice}, + {"help", no_argument, 0, OptHelp}, + {"list-registers", required_argument, 0, OptListRegisters}, + {"set-register", required_argument, 0, OptSetRegister}, + {"list-chip-idents", no_argument, 0, OptListChipIdents}, + {"get-chip-ident", required_argument, 0, OptGetChipIdent}, + {"info", no_argument, 0, OptGetDriverInfo}, + {"verbose", no_argument, 0, OptVerbose}, + {"log-status", no_argument, 0, OptLogStatus}, + {0, 0, 0, 0} +}; + +static void usage(void) +{ + printf("Usage:\n"); + printf(" -D, --info show driver info [VIDIOC_QUERYCAP]\n"); + printf(" -d, --device= use device instead of /dev/video0\n"); + printf(" if is a single digit, then /dev/video is used\n"); + printf(" -h, --help display this help message\n"); + printf(" --verbose turn on verbose ioctl error reporting.\n"); + printf(" -R, --list-registers=type=,chip=[,min=,max=] \n"); + printf(" dump registers from to [VIDIOC_DBG_G_REGISTER]\n"); + printf(" -r, --set-register=type=,chip=,reg=,val=\n"); + printf(" set the register [VIDIOC_DBG_S_REGISTER]\n"); + printf(" -C, --list-chip-idents\n"); + printf(" List the available host and i2c chips [VIDIOC_G_CHIP_IDENT]\n"); + printf(" -c, --get-chip-ident=type=,chip=\n"); + printf(" Get the chip identifier [VIDIOC_G_CHIP_IDENT]\n"); + printf(" --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n"); + printf("\n"); + printf(" if type == host, then is the host's chip ID (default 0)\n"); + printf(" if type == i2cdrv (default), then is the I2C driver name or ID\n"); + printf(" if type == i2caddr, then is the 7-bit I2C address\n"); + exit(0); +} + +static unsigned parse_type(const std::string &s) +{ + if (s == "host") return V4L2_CHIP_MATCH_HOST; + if (s == "i2caddr") return V4L2_CHIP_MATCH_I2C_ADDR; + return V4L2_CHIP_MATCH_I2C_DRIVER; +} + +/* Copied from */ +#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ +#define I2C_DRIVERID_SAA717X 80 /* saa717x video encoder */ +#define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */ +#define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */ + +static unsigned parse_chip(int type, const std::string &s) +{ + if (type == V4L2_CHIP_MATCH_HOST || type == V4L2_CHIP_MATCH_I2C_ADDR || isdigit(s[0])) + return strtoul(s.c_str(), 0, 0); + if (s == "saa711x") + return I2C_DRIVERID_SAA711X; + if (s == "saa717x") + return I2C_DRIVERID_SAA717X; + if (s == "saa7127") + return I2C_DRIVERID_SAA7127; + if (s == "cx2584x") + return I2C_DRIVERID_CX25840; + return 0; +} + +static std::string cap2s(unsigned cap) +{ + std::string s; + + if (cap & V4L2_CAP_VIDEO_CAPTURE) + s += "\t\tVideo Capture\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT) + s += "\t\tVideo Output\n"; + if (cap & V4L2_CAP_VIDEO_OVERLAY) + s += "\t\tVideo Overlay\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) + s += "\t\tVideo Output Overlay\n"; + if (cap & V4L2_CAP_VBI_CAPTURE) + s += "\t\tVBI Capture\n"; + if (cap & V4L2_CAP_VBI_OUTPUT) + s += "\t\tVBI Output\n"; + if (cap & V4L2_CAP_SLICED_VBI_CAPTURE) + s += "\t\tSliced VBI Capture\n"; + if (cap & V4L2_CAP_SLICED_VBI_OUTPUT) + s += "\t\tSliced VBI Output\n"; + if (cap & V4L2_CAP_RDS_CAPTURE) + s += "\t\tRDS Capture\n"; + if (cap & V4L2_CAP_VIDEO_OUTPUT_POS) + s += "\t\tVideo Output Position\n"; + if (cap & V4L2_CAP_TUNER) + s += "\t\tTuner\n"; + if (cap & V4L2_CAP_AUDIO) + s += "\t\tAudio\n"; + if (cap & V4L2_CAP_RADIO) + s += "\t\tRadio\n"; + if (cap & V4L2_CAP_READWRITE) + s += "\t\tRead/Write\n"; + if (cap & V4L2_CAP_ASYNCIO) + s += "\t\tAsync I/O\n"; + if (cap & V4L2_CAP_STREAMING) + s += "\t\tStreaming\n"; + return s; +} + +static void print_regs(int fd, struct v4l2_register *reg, unsigned long min, unsigned long max, int stride) +{ + unsigned long mask = stride > 1 ? 0x1f : 0x0f; + unsigned long i; + int line = 0; + + for (i = min & ~mask; i <= max; i += stride) { + if ((i & mask) == 0 && line % 32 == 0) { + if (stride == 4) + printf("\n 00 04 08 0C 10 14 18 1C"); + else + printf("\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); + } + + if ((i & mask) == 0) { + printf("\n%08lx: ", i); + line++; + } + if (i < min) { + printf("%*s ", 2 * stride, ""); + continue; + } + reg->reg = i; + if (ioctl(fd, VIDIOC_DBG_G_REGISTER, reg) < 0) { + fprintf(stderr, "ioctl: VIDIOC_DBG_G_REGISTER " + "failed for 0x%llx\n", reg->reg); + } else { + printf("%0*llx ", 2 * stride, reg->val); + } + usleep(1); + } + printf("\n"); +} + +static void print_chip(struct v4l2_chip_ident *chip) +{ + printf("Chip %d, revision 0x%08x\n", chip->ident, chip->revision); +} + +static int doioctl(int fd, int request, void *parm, const char *name) +{ + int retVal; + + if (!options[OptVerbose]) return ioctl(fd, request, parm); + retVal = ioctl(fd, request, parm); + printf("%s: ", name); + if (retVal < 0) + printf("failed: %s\n", strerror(errno)); + else + printf("ok\n"); + + return retVal; +} + +static int parse_subopt(char **subs, char * const *subopts, char **value) +{ + int opt = getsubopt(subs, subopts, value); + + if (opt == -1) { + fprintf(stderr, "Invalid suboptions specified\n"); + usage(); + exit(1); + } + if (value == NULL) { + fprintf(stderr, "No value given to suboption <%s>\n", + subopts[opt]); + usage(); + exit(1); + } + return opt; +} + +int main(int argc, char **argv) +{ + char *value, *subs; + int i; + + int fd = -1; + + /* command args */ + int ch; + char *device = strdup("/dev/video0"); /* -d device */ + struct v4l2_capability vcap; /* list_cap */ + struct v4l2_register set_reg; + struct v4l2_register get_reg; + struct v4l2_chip_ident chip_id; + char short_options[26 * 2 * 2 + 1]; + int idx = 0; + unsigned long long reg_min = 0, reg_max = 0; + + memset(&set_reg, 0, sizeof(set_reg)); + memset(&get_reg, 0, sizeof(get_reg)); + memset(&chip_id, 0, sizeof(chip_id)); + + if (argc == 1) { + usage(); + return 0; + } + for (i = 0; long_options[i].name; i++) { + if (!isalpha(long_options[i].val)) + continue; + short_options[idx++] = long_options[i].val; + if (long_options[i].has_arg == required_argument) + short_options[idx++] = ':'; + } + while (1) { + int option_index = 0; + + short_options[idx] = 0; + ch = getopt_long(argc, argv, short_options, + long_options, &option_index); + if (ch == -1) + break; + + options[(int)ch] = 1; + switch (ch) { + case OptHelp: + usage(); + return 0; + case OptSetDevice: + device = strdup(optarg); + if (device[0] >= '0' && device[0] <= '9' && device[1] == 0) { + char dev = device[0]; + + sprintf(device, "/dev/video%c", dev); + } + break; + case OptSetRegister: + subs = optarg; + set_reg.match_type = V4L2_CHIP_MATCH_I2C_DRIVER; + while (*subs != '\0') { + static char *const subopts[] = { + "type", + "chip", + "reg", + "val", + NULL + }; + + switch (parse_subopt(&subs, subopts, &value)) { + case 0: + set_reg.match_type = parse_type(value); + break; + case 1: + set_reg.match_chip = parse_chip(set_reg.match_type, value); + break; + case 2: + set_reg.reg = strtoull(value, 0L, 0); + break; + case 3: + set_reg.val = strtoull(value, 0L, 0); + break; + } + } + break; + case OptListRegisters: + subs = optarg; + get_reg.match_type = V4L2_CHIP_MATCH_I2C_DRIVER; + while (*subs != '\0') { + static char *const subopts[] = { + "type", + "chip", + "min", + "max", + NULL + }; + + switch (parse_subopt(&subs, subopts, &value)) { + case 0: + get_reg.match_type = parse_type(value); + break; + case 1: + get_reg.match_chip = parse_chip(set_reg.match_type, value); + break; + case 2: + reg_min = strtoull(value, 0L, 0); + break; + case 3: + reg_max = strtoull(value, 0L, 0); + break; + } + } + break; + case OptGetChipIdent: + subs = optarg; + set_reg.match_type = V4L2_CHIP_MATCH_I2C_DRIVER; + while (*subs != '\0') { + static char *const subopts[] = { + "type", + "chip", + NULL + }; + + switch (parse_subopt(&subs, subopts, &value)) { + case 0: + chip_id.match_type = parse_type(value); + break; + case 1: + chip_id.match_chip = parse_chip(set_reg.match_type, value); + break; + } + } + break; + case ':': + fprintf(stderr, "Option `%s' requires a value\n", + argv[optind]); + usage(); + return 1; + case '?': + fprintf(stderr, "Unknown argument `%s'\n", + argv[optind]); + usage(); + return 1; + } + } + if (optind < argc) { + printf("unknown arguments: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + usage(); + return 1; + } + + if ((fd = open(device, O_RDWR)) < 0) { + fprintf(stderr, "Failed to open %s: %s\n", device, + strerror(errno)); + exit(1); + } + free(device); + + doioctl(fd, VIDIOC_QUERYCAP, &vcap, "VIDIOC_QUERYCAP"); + capabilities = vcap.capabilities; + + /* Information Opts */ + + if (options[OptGetDriverInfo]) { + printf("Driver info:\n"); + printf("\tDriver name : %s\n", vcap.driver); + printf("\tCard type : %s\n", vcap.card); + printf("\tBus info : %s\n", vcap.bus_info); + printf("\tDriver version: %d\n", vcap.version); + printf("\tCapabilities : 0x%08X\n", vcap.capabilities); + printf("%s", cap2s(vcap.capabilities).c_str()); + } + + /* Set options */ + + if (options[OptSetRegister]) { + if (doioctl(fd, VIDIOC_DBG_S_REGISTER, &set_reg, + "VIDIOC_DBG_S_REGISTER") == 0) + printf("register 0x%llx set to 0x%llx\n", set_reg.reg, set_reg.val); + } + + if (options[OptGetChipIdent]) { + if (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") == 0) + print_chip(&chip_id); + } + + if (options[OptListChipIdents]) { + int i; + + chip_id.match_type = V4L2_CHIP_MATCH_HOST; + chip_id.match_chip = 0; + chip_id.ident = 0; + + if (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") == 0 && chip_id.ident) + print_chip(&chip_id); + + chip_id.match_type = V4L2_CHIP_MATCH_I2C_ADDR; + for (i = 0; i < 128; i++) { + chip_id.match_chip = i; + chip_id.ident = 0; + if (doioctl(fd, VIDIOC_G_CHIP_IDENT, &chip_id, "VIDIOC_G_CHIP_IDENT") == 0 && chip_id.ident) { + printf("0x%02x: ", i); + print_chip(&chip_id); + } + } + } + + if (options[OptListRegisters]) { + int stride = 1; + + if (get_reg.match_type == V4L2_CHIP_MATCH_HOST) stride = 4; + printf("ioctl: VIDIOC_DBG_G_REGISTER\n"); + if (reg_max == 0) { + switch (get_reg.match_chip) { + case I2C_DRIVERID_SAA711X: + print_regs(fd, &get_reg, 0, 0xff, stride); + break; + case I2C_DRIVERID_SAA717X: + // FIXME: use correct reg regions + print_regs(fd, &get_reg, 0, 0xff, stride); + break; + case I2C_DRIVERID_SAA7127: + print_regs(fd, &get_reg, 0, 0x7f, stride); + break; + case I2C_DRIVERID_CX25840: + print_regs(fd, &get_reg, 0, 2, stride); + print_regs(fd, &get_reg, 0x100, 0x15f, stride); + print_regs(fd, &get_reg, 0x200, 0x23f, stride); + print_regs(fd, &get_reg, 0x400, 0x4bf, stride); + print_regs(fd, &get_reg, 0x800, 0x9af, stride); + break; + case 0: + print_regs(fd, &get_reg, 0x02000000, 0x020000ff, stride); + break; + } + } + else { + print_regs(fd, &get_reg, reg_min, reg_max, stride); + } + } + + if (options[OptLogStatus]) { + static char buf[40960]; + int len; + + if (doioctl(fd, VIDIOC_LOG_STATUS, NULL, "VIDIOC_LOG_STATUS") == 0) { + printf("\nStatus Log:\n\n"); + len = klogctl(3, buf, sizeof(buf) - 1); + if (len >= 0) { + char *p = buf; + char *q; + + buf[len] = 0; + while ((q = strstr(p, "START STATUS CARD #"))) { + p = q + 1; + } + if (p) { + while (p > buf && *p != '<') p--; + q = p; + while ((q = strstr(q, "<6>"))) { + memcpy(q, " ", 3); + } + printf("%s", p); + } + } + } + } + + close(fd); + exit(0); +} -- cgit v1.2.3 From 29dc3ffaee320cff68d0ef8a2d9e2e0f112df29d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 25 Feb 2007 11:23:57 +0100 Subject: Add cx23415/6 chip idents. From: Hans Verkuil Signed-off-by: Hans Verkuil --- linux/include/media/v4l2-chip-ident.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index 67a34d528..5698fcd1d 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -55,6 +55,10 @@ enum { /* OmniVision sensors - range 250-299 */ V4L2_IDENT_OV7670 = 250, + + /* Conexant MPEG encoder/decoders: range 410-420 */ + V4L2_IDENT_CX23415 = 415, + V4L2_IDENT_CX23416 = 416, }; #endif -- cgit v1.2.3