The patch number 10690 was added via Mauro Carvalho Chehab <mche...@redhat.com> to http://linuxtv.org/hg/v4l-dvb master development tree.
Kernel patches in this development tree may be modified to be backward compatible with older kernels. Compatibility modifications will be removed before inclusion into the mainstream Kernel If anyone has any objections, please let us know by sending a message to: Linux Media Mailing List <linux-me...@vger.kernel.org> ------ From: Mauro Carvalho Chehab <mche...@redhat.com> merge: http://www.linuxtv.org/hg/~hverkuil/v4l-dvb Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com> --- linux/drivers/media/video/v4l2-common.c | 43 +++++++- linux/include/linux/videodev2.h | 1 v4l/scripts/make_config_compat.pl | 7 + v4l2-apps/util/v4l2-ctl.cpp | 123 +++++++++++++++++++++++- v4l2-spec/compat.sgml | 11 ++ v4l2-spec/controls.sgml | 33 +++--- v4l2-spec/vidioc-queryctrl.sgml | 15 ++ 7 files changed, 209 insertions(+), 24 deletions(-) diff -r aacca3f9c580 -r f546b826a749 linux/drivers/media/video/v4l2-common.c --- a/linux/drivers/media/video/v4l2-common.c Thu Feb 26 15:35:40 2009 -0300 +++ b/linux/drivers/media/video/v4l2-common.c Thu Feb 26 15:41:03 2009 -0300 @@ -333,6 +333,12 @@ const char **v4l2_ctrl_get_menu(u32 id) "Manual Mode", "Shutter Priority Mode", "Aperture Priority Mode", + NULL + }; + static const char *colorfx[] = { + "None", + "Black & White", + "Sepia", NULL }; @@ -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_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_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_AUDIO_VOLUME: return "Volume"; + 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_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,15 +500,24 @@ int v4l2_ctrl_query_fill(struct v4l2_que 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: @@ -518,6 +536,7 @@ int v4l2_ctrl_query_fill(struct v4l2_que 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,7 +567,16 @@ int v4l2_ctrl_query_fill(struct v4l2_que 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; @@ -569,6 +597,7 @@ int v4l2_ctrl_query_fill_std(struct v4l2 /* 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 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 -r aacca3f9c580 -r f546b826a749 linux/include/linux/videodev2.h --- a/linux/include/linux/videodev2.h Thu Feb 26 15:35:40 2009 -0300 +++ b/linux/include/linux/videodev2.h Thu Feb 26 15:41:03 2009 -0300 @@ -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 -r aacca3f9c580 -r f546b826a749 v4l/scripts/make_config_compat.pl --- a/v4l/scripts/make_config_compat.pl Thu Feb 26 15:35:40 2009 -0300 +++ b/v4l/scripts/make_config_compat.pl Thu Feb 26 15:41:03 2009 -0300 @@ -277,6 +277,13 @@ open IN, "<$infile" or die "File not fou $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 -r aacca3f9c580 -r f546b826a749 v4l2-apps/util/v4l2-ctl.cpp --- a/v4l2-apps/util/v4l2-ctl.cpp Thu Feb 26 15:35:40 2009 -0300 +++ b/v4l2-apps/util/v4l2-ctl.cpp Thu Feb 26 15:41:03 2009 -0300 @@ -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 v } 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()); @@ -748,6 +763,35 @@ static void printfbuf(const struct v4l2_ if (fb.fmt.priv) printf("\tCustom Info : %08x\n", fb.fmt.priv); } +} + +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) @@ -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"); } @@ -2108,6 +2215,12 @@ set_vid_fmt_error: struct v4l2_framebuffer fb; if (doioctl(fd, VIDIOC_G_FBUF, &fb, "VIDIOC_G_FBUF") == 0) 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]) { diff -r aacca3f9c580 -r f546b826a749 v4l2-spec/compat.sgml --- a/v4l2-spec/compat.sgml Thu Feb 26 15:35:40 2009 -0300 +++ b/v4l2-spec/compat.sgml Thu Feb 26 15:41:03 2009 -0300 @@ -2281,6 +2281,17 @@ was renamed to <structname id=v4l2-chip- <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 -r aacca3f9c580 -r f546b826a749 v4l2-spec/controls.sgml --- a/v4l2-spec/controls.sgml Thu Feb 26 15:35:40 2009 -0300 +++ b/v4l2-spec/controls.sgml Thu Feb 26 15:41:03 2009 -0300 @@ -271,11 +271,20 @@ minimum value disables backlight compens <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 @@ camera horizontally by the specified amo 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.</ent </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 -r aacca3f9c580 -r f546b826a749 v4l2-spec/vidioc-queryctrl.sgml --- a/v4l2-spec/vidioc-queryctrl.sgml Thu Feb 26 15:35:40 2009 -0300 +++ b/v4l2-spec/vidioc-queryctrl.sgml Thu Feb 26 15:41:03 2009 -0300 @@ -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> @@ -376,6 +385,12 @@ slider-like element in a user interface. <para>The &v4l2-queryctrl; <structfield>id</structfield> 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> --- Patch is available at: http://linuxtv.org/hg/v4l-dvb/rev/f546b826a749eb78f3a882093f1d7e27b6ef910c _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits