diff options
-rw-r--r-- | linux/drivers/media/video/v4l2-common.c | 41 | ||||
-rw-r--r-- | linux/include/linux/videodev2.h | 1 | ||||
-rwxr-xr-x | v4l/scripts/make_config_compat.pl | 7 | ||||
-rw-r--r-- | v4l2-apps/util/v4l2-ctl.cpp | 123 | ||||
-rw-r--r-- | v4l2-spec/compat.sgml | 11 | ||||
-rw-r--r-- | v4l2-spec/controls.sgml | 33 | ||||
-rw-r--r-- | v4l2-spec/vidioc-queryctrl.sgml | 15 |
7 files changed, 208 insertions, 23 deletions
diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index 8ae8dd366..c2d71816e 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -335,6 +335,12 @@ const char **v4l2_ctrl_get_menu(u32 id) "Aperture Priority Mode", NULL }; + static const char *colorfx[] = { + "None", + "Black & White", + "Sepia", + NULL + }; switch (id) { case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: @@ -371,6 +377,8 @@ const char **v4l2_ctrl_get_menu(u32 id) return camera_power_line_frequency; case V4L2_CID_EXPOSURE_AUTO: return camera_exposure_auto; + case V4L2_CID_COLORFX: + return colorfx; default: return NULL; } @@ -383,16 +391,16 @@ const char *v4l2_ctrl_get_name(u32 id) switch (id) { /* USER controls */ case V4L2_CID_USER_CLASS: return "User Controls"; + case V4L2_CID_BRIGHTNESS: return "Brightness"; + case V4L2_CID_CONTRAST: return "Contrast"; + case V4L2_CID_SATURATION: return "Saturation"; + case V4L2_CID_HUE: return "Hue"; case V4L2_CID_AUDIO_VOLUME: return "Volume"; - case V4L2_CID_AUDIO_MUTE: return "Mute"; case V4L2_CID_AUDIO_BALANCE: return "Balance"; case V4L2_CID_AUDIO_BASS: return "Bass"; case V4L2_CID_AUDIO_TREBLE: return "Treble"; + case V4L2_CID_AUDIO_MUTE: return "Mute"; case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; - case V4L2_CID_BRIGHTNESS: return "Brightness"; - case V4L2_CID_CONTRAST: return "Contrast"; - case V4L2_CID_SATURATION: return "Saturation"; - case V4L2_CID_HUE: return "Hue"; case V4L2_CID_BLACK_LEVEL: return "Black Level"; case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic"; case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance"; @@ -413,6 +421,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation"; case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; case V4L2_CID_COLOR_KILLER: return "Color Killer"; + case V4L2_CID_COLORFX: return "Color Effects"; /* MPEG controls */ case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; @@ -491,16 +500,25 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_HFLIP: case V4L2_CID_VFLIP: case V4L2_CID_HUE_AUTO: + case V4L2_CID_CHROMA_AGC: + case V4L2_CID_COLOR_KILLER: case V4L2_CID_MPEG_AUDIO_MUTE: case V4L2_CID_MPEG_VIDEO_MUTE: case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: case V4L2_CID_MPEG_VIDEO_PULLDOWN: case V4L2_CID_EXPOSURE_AUTO_PRIORITY: + case V4L2_CID_FOCUS_AUTO: case V4L2_CID_PRIVACY: qctrl->type = V4L2_CTRL_TYPE_BOOLEAN; min = 0; max = step = 1; break; + case V4L2_CID_PAN_RESET: + case V4L2_CID_TILT_RESET: + qctrl->type = V4L2_CTRL_TYPE_BUTTON; + qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; + min = max = step = def = 0; + break; case V4L2_CID_POWER_LINE_FREQUENCY: case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: case V4L2_CID_MPEG_AUDIO_ENCODING: @@ -518,6 +536,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_MPEG_STREAM_TYPE: case V4L2_CID_MPEG_STREAM_VBI_FMT: case V4L2_CID_EXPOSURE_AUTO: + case V4L2_CID_COLORFX: qctrl->type = V4L2_CTRL_TYPE_MENU; step = 1; break; @@ -548,8 +567,17 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste case V4L2_CID_CONTRAST: case V4L2_CID_SATURATION: case V4L2_CID_HUE: + case V4L2_CID_RED_BALANCE: + case V4L2_CID_BLUE_BALANCE: + case V4L2_CID_GAMMA: qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; break; + case V4L2_CID_PAN_RELATIVE: + case V4L2_CID_TILT_RELATIVE: + case V4L2_CID_FOCUS_RELATIVE: + case V4L2_CID_ZOOM_RELATIVE: + qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; + break; } qctrl->minimum = min; qctrl->maximum = max; @@ -569,6 +597,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) /* USER controls */ case V4L2_CID_USER_CLASS: case V4L2_CID_MPEG_CLASS: + case V4L2_CID_CAMERA_CLASS: return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0); case V4L2_CID_AUDIO_VOLUME: return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880); @@ -586,6 +615,8 @@ int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl) return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64); case V4L2_CID_HUE: return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0); + case V4L2_CID_COLORFX: + return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0); /* MPEG controls */ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index 6969c3086..4167a0b44 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -830,6 +830,7 @@ struct v4l2_querymenu { #define V4L2_CTRL_FLAG_UPDATE 0x0008 #define V4L2_CTRL_FLAG_INACTIVE 0x0010 #define V4L2_CTRL_FLAG_SLIDER 0x0020 +#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 /* Query flag, to be ORed with the control ID */ #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 diff --git a/v4l/scripts/make_config_compat.pl b/v4l/scripts/make_config_compat.pl index d24b5f718..423dcff77 100755 --- a/v4l/scripts/make_config_compat.pl +++ b/v4l/scripts/make_config_compat.pl @@ -277,6 +277,13 @@ open IN, "<$infile" or die "File not found: $infile"; $out.= "#ifndef __CONFIG_COMPAT_H__\n"; $out.= "#define __CONFIG_COMPAT_H__\n\n"; $out.= "#include <linux/autoconf.h>\n\n"; + +# mmdebug.h includes autoconf.h. So if this header exists, +# then include it before our config is set. +if (-f "$kdir/include/linux/mmdebug.h") { + $out.= "#include <linux/mmdebug.h>\n\n"; +} + while(<IN>) { next unless /^(\S+)\s*:= (\S+)$/; $out.= "#undef $1\n"; diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 7d5988571..dec9edd61 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -129,6 +129,8 @@ enum Option { OptGetOverlayCropCap, OptGetOutputOverlayCropCap, OptOverlay, + OptGetJpegComp, + OptSetJpegComp, OptListDevices, OptLast = 256 }; @@ -256,6 +258,8 @@ static struct option long_options[] = { {"get-cropcap-output-overlay", no_argument, 0, OptGetOutputOverlayCropCap}, {"get-crop-output-overlay", no_argument, 0, OptGetOutputOverlayCrop}, {"set-crop-output-overlay", required_argument, 0, OptSetOutputOverlayCrop}, + {"get-jpeg-comp", no_argument, 0, OptGetJpegComp}, + {"set-jpeg-comp", required_argument, 0, OptSetJpegComp}, {"overlay", required_argument, 0, OptOverlay}, {"list-devices", no_argument, 0, OptListDevices}, {0, 0, 0, 0} @@ -380,6 +384,16 @@ static void usage(void) " query the video output overlay crop window [VIDIOC_G_CROP]\n" " --set-crop-output-overlay=top=<x>,left=<y>,width=<w>,height=<h>\n" " set the video output overlay crop window [VIDIOC_S_CROP]\n" + " --get-jpeg-comp query the JPEG compression [VIDIOC_G_JPEGCOMP]\n" + " --set-jpeg-comp=quality=<q>,markers=<markers>,comment=<c>,app<n>=<a>\n" + " set the JPEG compression [VIDIOC_S_JPEGCOMP]\n" + " <n> is the app segment: 0-9 or a-f, <a> is the actual string.\n" + " <markers> is a colon separated list of:\n" + " dht: Define Huffman Tables\n" + " dqt: Define Quantization Tables\n" + " dri: Define Restart Interval\n" + " --set-audio-output=<num>\n" + " set the audio output to <num> [VIDIOC_S_AUDOUT]\n" " --get-audio-input query the audio input [VIDIOC_G_AUDIO]\n" " --set-audio-input=<num>\n" " set the audio input to <num> [VIDIOC_S_AUDIO]\n" @@ -576,11 +590,12 @@ static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl, } if (queryctrl->flags) { const flag_def def[] = { - { V4L2_CTRL_FLAG_GRABBED, "grabbed" }, - { V4L2_CTRL_FLAG_READ_ONLY, "readonly" }, - { V4L2_CTRL_FLAG_UPDATE, "update" }, - { V4L2_CTRL_FLAG_INACTIVE, "inactive" }, - { V4L2_CTRL_FLAG_SLIDER, "slider" }, + { V4L2_CTRL_FLAG_GRABBED, "grabbed" }, + { V4L2_CTRL_FLAG_READ_ONLY, "read-only" }, + { V4L2_CTRL_FLAG_UPDATE, "update" }, + { V4L2_CTRL_FLAG_INACTIVE, "inactive" }, + { V4L2_CTRL_FLAG_SLIDER, "slider" }, + { V4L2_CTRL_FLAG_WRITE_ONLY, "write-only" }, { 0, NULL } }; printf(" flags=%s", flags2s(queryctrl->flags, def).c_str()); @@ -750,6 +765,35 @@ static void printfbuf(const struct v4l2_framebuffer &fb) } } +static std::string markers2s(unsigned markers) +{ + std::string s; + + if (markers & V4L2_JPEG_MARKER_DHT) + s += "\t\tDefine Huffman Tables\n"; + if (markers & V4L2_JPEG_MARKER_DQT) + s += "\t\tDefine Quantization Tables\n"; + if (markers & V4L2_JPEG_MARKER_DRI) + s += "\t\tDefine Restart Interval\n"; + if (markers & V4L2_JPEG_MARKER_COM) + s += "\t\tDefine Comment\n"; + if (markers & V4L2_JPEG_MARKER_APP) + s += "\t\tDefine APP segment\n"; + return s; +} + +static void printjpegcomp(const struct v4l2_jpegcompression &jc) +{ + printf("JPEG compression:\n"); + printf("\tQuality: %d\n", jc.quality); + if (jc.COM_len) + printf("\tComment: '%s'\n", jc.COM_data); + if (jc.APP_len) + printf("\tAPP%x : '%s'\n", jc.APPn, jc.APP_data); + printf("\tMarkers: 0x%08lx\n", jc.jpeg_markers); + printf("%s", markers2s(jc.jpeg_markers).c_str()); +} + static void printcrop(const struct v4l2_crop &crop) { printf("Crop: Left %d, Top %d, Width %d, Height %d\n", @@ -1337,6 +1381,7 @@ int main(int argc, char **argv) struct v4l2_rect vcrop_overlay; /* crop rect */ struct v4l2_rect vcrop_out_overlay; /* crop rect */ struct v4l2_framebuffer fbuf; /* fbuf */ + struct v4l2_jpegcompression jpegcomp; /* jpeg compression */ int input; /* set_input/get_input */ int output; /* set_output/get_output */ v4l2_std_id std; /* get_std/set_std */ @@ -1371,6 +1416,7 @@ int main(int argc, char **argv) memset(&vf, 0, sizeof(vf)); memset(&vs, 0, sizeof(vs)); memset(&fbuf, 0, sizeof(fbuf)); + memset(&jpegcomp, 0, sizeof(jpegcomp)); if (argc == 1) { usage(); @@ -1700,6 +1746,62 @@ int main(int argc, char **argv) } break; } + case OptSetJpegComp: + { + subs = optarg; + while (*subs != '\0') { + static const char *const subopts[] = { + "app0", "app1", "app2", "app3", + "app4", "app5", "app6", "app7", + "app8", "app9", "appa", "appb", + "appc", "appd", "appe", "appf", + "quality", + "markers", + "comment", + NULL + }; + int len; + int opt = parse_subopt(&subs, subopts, &value); + + switch (opt) { + case 16: + jpegcomp.quality = strtol(value, 0L, 0); + break; + case 17: + if (strstr(value, "dht")) + jpegcomp.jpeg_markers |= V4L2_JPEG_MARKER_DHT; + if (strstr(value, "dqt")) + jpegcomp.jpeg_markers |= V4L2_JPEG_MARKER_DQT; + if (strstr(value, "dri")) + jpegcomp.jpeg_markers |= V4L2_JPEG_MARKER_DRI; + break; + case 18: + len = strlen(value); + if (len > sizeof(jpegcomp.COM_data) - 1) + len = sizeof(jpegcomp.COM_data) - 1; + jpegcomp.COM_len = len; + memcpy(jpegcomp.COM_data, value, len); + jpegcomp.COM_data[len] = '\0'; + break; + default: + if (opt < 0 || opt > 15) + break; + len = strlen(value); + if (len > sizeof(jpegcomp.APP_data) - 1) + len = sizeof(jpegcomp.APP_data) - 1; + if (jpegcomp.APP_len) { + fprintf(stderr, "Only one APP segment can be set\n"); + break; + } + jpegcomp.APP_len = len; + memcpy(jpegcomp.APP_data, value, len); + jpegcomp.APP_data[len] = '\0'; + jpegcomp.APPn = opt; + break; + } + } + break; + } case OptListDevices: list_devices(); break; @@ -1768,6 +1870,7 @@ int main(int argc, char **argv) options[OptGetFBuf] = 1; options[OptGetCropCap] = 1; options[OptGetOutputCropCap] = 1; + options[OptGetJpegComp] = 1; options[OptSilent] = 1; } @@ -1987,6 +2090,10 @@ set_vid_fmt_error: } } + if (options[OptSetJpegComp]) { + doioctl(fd, VIDIOC_S_JPEGCOMP, &jpegcomp, "VIDIOC_S_JPEGCOMP"); + } + if (options[OptOverlay]) { doioctl(fd, VIDIOC_OVERLAY, &overlay, "VIDIOC_OVERLAY"); } @@ -2110,6 +2217,12 @@ set_vid_fmt_error: printfbuf(fb); } + if (options[OptGetJpegComp]) { + struct v4l2_jpegcompression jc; + if (doioctl(fd, VIDIOC_G_JPEGCOMP, &jc, "VIDIOC_G_JPEGCOMP") == 0) + printjpegcomp(jc); + } + if (options[OptGetCropCap]) { struct v4l2_cropcap cropcap; diff --git a/v4l2-spec/compat.sgml b/v4l2-spec/compat.sgml index 8c3177b22..94713023d 100644 --- a/v4l2-spec/compat.sgml +++ b/v4l2-spec/compat.sgml @@ -2281,6 +2281,17 @@ was renamed to <structname id=v4l2-chip-ident-old>v4l2_chip_ident_old</structnam <constant>V4L2_CID_ZOOM_CONTINUOUS</constant> and <constant>V4L2_CID_PRIVACY</constant>.</para> </listitem> + </orderedlist> + </section> + <section> + <title>V4L2 in Linux 2.6.30</title> + <orderedlist> + <listitem> + <para>New control flag <constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant> was added.</para> + </listitem> + <listitem> + <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para> + </listitem> </orderedlist> </section> </section> diff --git a/v4l2-spec/controls.sgml b/v4l2-spec/controls.sgml index 0df57dcf7..477a97077 100644 --- a/v4l2-spec/controls.sgml +++ b/v4l2-spec/controls.sgml @@ -271,11 +271,20 @@ minimum value disables backlight compensation.</entry> <entry>boolean</entry> <entry>Enable the color killer (&ie; force a black & white image in case of a weak video signal).</entry> </row> + <row id="v4l2-colorfx"> + <entry><constant>V4L2_CID_COLORFX</constant></entry> + <entry>enum</entry> + <entry>Selects a color effect. Possible values for +<constant>enum v4l2_colorfx</constant> are: +<constant>V4L2_COLORFX_NONE</constant> (0), +<constant>V4L2_COLORFX_BW</constant> (1) and +<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry> + </row> <row> <entry><constant>V4L2_CID_LASTP1</constant></entry> <entry></entry> <entry>End of the predefined control IDs (currently -<constant>V4L2_CID_COLOR_KILLER</constant> + 1).</entry> +<constant>V4L2_CID_COLORFX</constant> + 1).</entry> </row> <row> <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry> @@ -1679,7 +1688,7 @@ remain constant.</entry> camera horizontally by the specified amount. The unit is undefined. A positive value moves the camera to the right (clockwise when viewed from above), a negative value to the left. A value of zero does not -cause motion.</entry> +cause motion. This is a write-only control.</entry> </row> <row><entry></entry></row> @@ -1689,25 +1698,23 @@ cause motion.</entry> </row><row><entry spanname="descr">This control turns the camera vertically by the specified amount. The unit is undefined. A positive value moves the camera up, a negative value down. A value of -zero does not cause motion.</entry> +zero does not cause motion. This is a write-only control.</entry> </row> <row><entry></entry></row> <row> <entry spanname="id"><constant>V4L2_CID_PAN_RESET</constant> </entry> - <entry>boolean</entry> - </row><row><entry spanname="descr">When this control is set -to <constant>TRUE</constant> (1), the camera moves horizontally to the -default position.</entry> + <entry>button</entry> + </row><row><entry spanname="descr">When this control is set, +the camera moves horizontally to the default position.</entry> </row> <row><entry></entry></row> <row> <entry spanname="id"><constant>V4L2_CID_TILT_RESET</constant> </entry> - <entry>boolean</entry> - </row><row><entry spanname="descr">When this control is set -to <constant>TRUE</constant> (1), the camera moves vertically to the -default position.</entry> + <entry>button</entry> + </row><row><entry spanname="descr">When this control is set, +the camera moves vertically to the default position.</entry> </row> <row><entry></entry></row> @@ -1750,7 +1757,7 @@ negative values towards infinity.</entry> </row><row><entry spanname="descr">This control moves the focal point of the camera by the specified amount. The unit is undefined. Positive values move the focus closer to the camera, -negative values towards infinity.</entry> +negative values towards infinity. This is a write-only control.</entry> </row> <row><entry></entry></row> @@ -1778,7 +1785,7 @@ value should be a positive integer.</entry> </row><row><entry spanname="descr">Specify the objective lens focal length relatively to the current value. Positive values move the zoom lens group towards the telephoto direction, negative values towards the -wide-angle direction. The zoom unit is driver-specific.</entry> +wide-angle direction. The zoom unit is driver-specific. This is a write-only control.</entry> </row> <row><entry></entry></row> diff --git a/v4l2-spec/vidioc-queryctrl.sgml b/v4l2-spec/vidioc-queryctrl.sgml index 20c4147eb..9908a964d 100644 --- a/v4l2-spec/vidioc-queryctrl.sgml +++ b/v4l2-spec/vidioc-queryctrl.sgml @@ -361,6 +361,15 @@ control.</entry> <entry>A hint that this control is best represented as a slider-like element in a user interface.</entry> </row> + <row> + <entry><constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant></entry> + <entry>0x0040</entry> + <entry>This control is permanently writable only. Any +attempt to read the control will result in an &EACCES; error code. This +flag is typically present for relative controls or action controls where +writing a value will cause the device to carry out a given action +(⪚ motor control) but no meaningful value can be returned.</entry> + </row> </tbody> </tgroup> </table> @@ -378,6 +387,12 @@ is invalid. The &v4l2-querymenu; <structfield>id</structfield> or <structfield>index</structfield> is invalid.</para> </listitem> </varlistentry> + <varlistentry> + <term><errorcode>EACCES</errorcode></term> + <listitem> + <para>An attempt was made to read a write-only control.</para> + </listitem> + </varlistentry> </variablelist> </refsect1> </refentry> |