summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/drivers/media/video/v4l2-common.c41
-rw-r--r--linux/include/linux/videodev2.h1
-rwxr-xr-xv4l/scripts/make_config_compat.pl7
-rw-r--r--v4l2-apps/util/v4l2-ctl.cpp123
-rw-r--r--v4l2-spec/compat.sgml11
-rw-r--r--v4l2-spec/controls.sgml33
-rw-r--r--v4l2-spec/vidioc-queryctrl.sgml15
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 &amp; 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>&nbsp;</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>&nbsp;</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
+(&eg; 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>