All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] v4l2-ctl: Add support for VIDIOC_G/S_SELECTION ioctls
@ 2012-07-22 20:42 Sylwester Nawrocki
  2012-07-23  9:02 ` Hans Verkuil
  0 siblings, 1 reply; 2+ messages in thread
From: Sylwester Nawrocki @ 2012-07-22 20:42 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, Sylwester Nawrocki

This patch adds following commands for the selection API ioctls:

--get-selection, --set-selection,
--get-selection-output, --set-selection-output.

All supported selection rectangles at a video node are now also
displayed in case of --all command.

Signed-off-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl.cpp |  239 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 239 insertions(+), 0 deletions(-)

diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 1a6c4ae..c70e88c 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -139,6 +139,10 @@ enum Option {
 	OptSetOverlayCrop,
 	OptGetOutputOverlayCrop,
 	OptSetOutputOverlayCrop,
+	OptGetSelection,
+	OptSetSelection,
+	OptGetOutputSelection,
+	OptSetOutputSelection,
 	OptGetAudioInput,
 	OptSetAudioInput,
 	OptGetAudioOutput,
@@ -233,6 +237,13 @@ static const flag_def service_def[] = {
 #define CropLeft		(1L<<2)
 #define CropTop 		(1L<<3)

+/* selection specified */
+#define SelectionWidth		(1L<<0)
+#define SelectionHeight		(1L<<1)
+#define SelectionLeft		(1L<<2)
+#define SelectionTop 		(1L<<3)
+#define SelectionFlags 		(1L<<4)
+
 static struct option long_options[] = {
 	{"list-audio-inputs", no_argument, 0, OptListAudioInputs},
 	{"list-audio-outputs", no_argument, 0, OptListAudioOutputs},
@@ -322,6 +333,10 @@ 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-selection", required_argument, 0, OptGetSelection},
+	{"set-selection", required_argument, 0, OptSetSelection},
+	{"get-selection-output", required_argument, 0, OptGetOutputSelection},
+	{"set-selection-output", required_argument, 0, OptSetOutputSelection},
 	{"get-jpeg-comp", no_argument, 0, OptGetJpegComp},
 	{"set-jpeg-comp", required_argument, 0, OptSetJpegComp},
 	{"get-modulator", no_argument, 0, OptGetModulator},
@@ -631,6 +646,26 @@ static void usage_crop(void)
 	       );
 }

+static void usage_selection(void)
+{
+	printf("\nSelection options:\n"
+	       "  --get-selection=target=<target>\n"
+	       "                     query the video capture selection rectangle [VIDIOC_G_SELECTION]\n"
+	       "                     See --set-selection command for the valid <target> values.\n"
+	       "  --set-selection=target=<target>,flags=<flags>,top=<x>,left=<y>,width=<w>,height=<h>\n"
+	       "                     set the video capture selection rectangle [VIDIOC_S_SELECTION]\n"
+	       "                     target=crop|crop_bounds|crop_default|compose|compose_bounds|\n"
+	       "                            compose_default|compose_padded\n"
+	       "                     flags=le|ge\n"
+	       "  --get-selection-output=target=<target>\n"
+	       "                     query the video output selection rectangle [VIDIOC_G_SELECTION]\n"
+	       "                     See --set-selection command for the valid <target> values.\n"
+	       "  --set-selection-output=target=<target>,flags=<flags>,top=<x>,left=<y>,width=<w>,height=<h>\n"
+	       "                     set the video output selection rectangle [VIDIOC_S_SELECTION]\n"
+	       "                     See --set-selection command for the arguments.\n"
+	       );
+}
+
 static void usage_misc(void)
 {
 	printf("\nMiscellaneous options:\n"
@@ -688,6 +723,7 @@ static void usage(void)
 	usage_vidout();
 	usage_overlay();
 	usage_vbi();
+	usage_selection();
 	usage_crop();
 	usage_misc();
 }
@@ -1267,6 +1303,35 @@ static void printcropcap(const struct v4l2_cropcap &cropcap)
 	printf("\tPixel Aspect: %u/%u\n", cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator);
 }

+static const flag_def selection_targets_def[] = {
+	{ V4L2_SEL_TGT_CROP_ACTIVE, "crop" },
+	{ V4L2_SEL_TGT_CROP_DEFAULT, "crop_default" },
+	{ V4L2_SEL_TGT_CROP_BOUNDS, "crop_bounds" },
+	{ V4L2_SEL_TGT_COMPOSE_ACTIVE, "compose" },
+	{ V4L2_SEL_TGT_COMPOSE_DEFAULT, "compose_default" },
+	{ V4L2_SEL_TGT_COMPOSE_BOUNDS, "compose_bounds" },
+	{ V4L2_SEL_TGT_COMPOSE_PADDED, "compose_padded" },
+	{ 0, NULL }
+};
+
+static std::string seltarget2s(__u32 target)
+{
+	int i = 0;
+
+	while (selection_targets_def[i++].str != NULL) {
+		if (selection_targets_def[i].flag == target)
+			return selection_targets_def[i].str;
+	}
+	return "Unknown";
+}
+
+static void print_selection(const struct v4l2_selection &sel)
+{
+	printf("Selection: %s, Left %d, Top %d, Width %d, Height %d\n",
+			seltarget2s(sel.target).c_str(),
+			sel.r.left, sel.r.top, sel.r.width, sel.r.height);
+}
+
 static void printfmt(const struct v4l2_format &vfmt)
 {
 	const flag_def vbi_def[] = {
@@ -2008,6 +2073,103 @@ static void parse_crop(char *optarg, unsigned int &set_crop, v4l2_rect &vcrop)
 	}
 }

+static void do_selection(int fd, unsigned int set_selection, struct v4l2_selection &vsel,
+			 v4l2_buf_type type)
+{
+	struct v4l2_selection in_selection;
+
+	in_selection.type = type;
+	in_selection.target = vsel.target;
+
+	if (doioctl(fd, VIDIOC_G_SELECTION, &in_selection) == 0) {
+		if (set_selection & SelectionWidth)
+			in_selection.r.width = vsel.r.width;
+		if (set_selection & SelectionHeight)
+			in_selection.r.height = vsel.r.height;
+		if (set_selection & SelectionLeft)
+			in_selection.r.left = vsel.r.left;
+		if (set_selection & SelectionTop)
+			in_selection.r.top = vsel.r.top;
+		in_selection.flags = (set_selection & SelectionFlags) ? vsel.flags : 0;
+		doioctl(fd, VIDIOC_S_SELECTION, &in_selection);
+	}
+}
+
+static int parse_selection_target(const char *s, unsigned int &target)
+{
+	if (!strcmp(s, "crop")) target = V4L2_SEL_TGT_CROP_ACTIVE;
+	else if (!strcmp(s, "crop_default")) target = V4L2_SEL_TGT_CROP_DEFAULT;
+	else if (!strcmp(s, "crop_bounds")) target = V4L2_SEL_TGT_CROP_BOUNDS;
+	else if (!strcmp(s, "compose")) target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
+	else if (!strcmp(s, "compose_default")) target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
+	else if (!strcmp(s, "compose_bounds")) target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
+	else if (!strcmp(s, "compose_padded")) target = V4L2_SEL_TGT_COMPOSE_PADDED;
+	else return -EINVAL;
+
+	return 0;
+}
+
+static int parse_selection_flags(const char *s)
+{
+	if (!strcmp(s, "le")) return V4L2_SEL_FLAG_LE;
+	if (!strcmp(s, "ge")) return V4L2_SEL_FLAG_GE;
+	return 0;
+}
+
+static int parse_selection(char *optarg, unsigned int &set_sel, v4l2_selection &vsel)
+{
+	char *value;
+	char *subs = optarg;
+
+	while (*subs != '\0') {
+		static const char *const subopts[] = {
+			"target",
+			"flags",
+			"left",
+			"top",
+			"width",
+			"height",
+			NULL
+		};
+
+		switch (parse_subopt(&subs, subopts, &value)) {
+		case 0:
+			if (parse_selection_target(value, vsel.target)) {
+				fprintf(stderr, "Unknown selection target\n");
+				usage_selection();
+				exit(1);
+			}
+			break;
+		case 1:
+			vsel.flags = parse_selection_flags(value);
+			set_sel |= SelectionFlags;
+			break;
+		case 2:
+			vsel.r.left = strtol(value, 0L, 0);
+			set_sel |= SelectionLeft;
+			break;
+		case 3:
+			vsel.r.top = strtol(value, 0L, 0);
+			set_sel |= SelectionTop;
+			break;
+		case 4:
+			vsel.r.width = strtol(value, 0L, 0);
+			set_sel |= SelectionWidth;
+			break;
+		case 5:
+			vsel.r.height = strtol(value, 0L, 0);
+			set_sel |= SelectionHeight;
+			break;
+		default:
+			fprintf(stderr, "Unknown option\n");
+			usage_selection();
+			exit(1);
+		}
+	}
+
+	return 0;
+}
+
 static void parse_freq_seek(char *optarg, struct v4l2_hw_freq_seek &seek)
 {
 	char *value;
@@ -2323,6 +2485,9 @@ int main(int argc, char **argv)
 	unsigned int set_crop_out = 0;
 	unsigned int set_crop_overlay = 0;
 	unsigned int set_crop_out_overlay = 0;
+	unsigned int set_selection = 0;
+	unsigned int set_selection_out = 0;
+	int get_sel_target = 0;
 	unsigned int set_fbuf = 0;
 	unsigned int set_overlay_fmt = 0;
 	unsigned int set_overlay_fmt_out = 0;
@@ -2353,6 +2518,8 @@ int main(int argc, char **argv)
 	struct v4l2_rect vcrop_out; 	/* crop rect */
 	struct v4l2_rect vcrop_overlay; 	/* crop rect */
 	struct v4l2_rect vcrop_out_overlay; 	/* crop rect */
+	struct v4l2_selection vselection; 	/* capture selection */
+	struct v4l2_selection vselection_out;	/* output selection */
 	struct v4l2_framebuffer fbuf;   /* fbuf */
 	struct v4l2_jpegcompression jpegcomp; /* jpeg compression */
 	struct v4l2_streamparm parm;	/* get/set parm */
@@ -2409,6 +2576,8 @@ int main(int argc, char **argv)
 	memset(&vcrop_out, 0, sizeof(vcrop_out));
 	memset(&vcrop_overlay, 0, sizeof(vcrop_overlay));
 	memset(&vcrop_out_overlay, 0, sizeof(vcrop_out_overlay));
+	memset(&vselection, 0, sizeof(vselection));
+	memset(&vselection_out, 0, sizeof(vselection_out));
 	memset(&vf, 0, sizeof(vf));
 	memset(&vs, 0, sizeof(vs));
 	memset(&fbuf, 0, sizeof(fbuf));
@@ -2694,6 +2863,25 @@ int main(int argc, char **argv)
 		case OptSetOutputOverlayCrop:
 			parse_crop(optarg, set_crop_out_overlay, vcrop_out_overlay);
 			break;
+		case OptSetSelection:
+			parse_selection(optarg, set_selection, vselection);
+			break;
+		case OptSetOutputSelection:
+			parse_selection(optarg, set_selection_out, vselection_out);
+			break;
+		case OptGetOutputSelection:
+		case OptGetSelection: {
+			struct v4l2_selection gsel;
+			unsigned int get_sel;
+
+			if (parse_selection(optarg, get_sel, gsel)) {
+				fprintf(stderr, "Unknown selection target\n");
+				usage_selection();
+				exit(1);
+			}
+			get_sel_target = gsel.target;
+			break;
+		}
 		case OptSetInput:
 			input = strtol(optarg, 0L, 0);
 			break;
@@ -3097,6 +3285,9 @@ int main(int argc, char **argv)
 		options[OptGetDvTimings] = 1;
 		options[OptGetDvTimingsCap] = 1;
 		options[OptGetPriority] = 1;
+		options[OptGetSelection] = 1;
+		options[OptGetOutputSelection] = 1;
+		get_sel_target = -1;
 		options[OptSilent] = 1;
 	}

@@ -3489,6 +3680,14 @@ int main(int argc, char **argv)
 		do_crop(fd, set_crop_out_overlay, vcrop_out_overlay, V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
 	}

+	if (options[OptSetSelection]) {
+		do_selection(fd, set_selection, vselection, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	}
+
+	if (options[OptSetOutputSelection]) {
+		do_selection(fd, set_selection_out, vselection_out, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	}
+
 	if (options[OptSetCtrl] && !set_ctrls.empty()) {
 		struct v4l2_ext_controls ctrls;
 		class2ctrls_map class2ctrls;
@@ -3720,6 +3919,46 @@ int main(int argc, char **argv)
 			printcrop(crop);
 	}

+	if (options[OptGetSelection]) {
+		struct v4l2_selection sel;
+		int t = 0;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+		if (get_sel_target == -1) {
+			while (selection_targets_def[t++].str != NULL) {
+				sel.target = selection_targets_def[t].flag;
+				if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
+					print_selection(sel);
+			}
+		} else {
+			sel.target = get_sel_target;
+			if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
+				print_selection(sel);
+		}
+	}
+
+	if (options[OptGetOutputSelection]) {
+		struct v4l2_selection sel;
+		int t = 0;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+		if (get_sel_target == -1) {
+			while (selection_targets_def[t++].str != NULL) {
+				sel.target = selection_targets_def[t].flag;
+				if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
+					print_selection(sel);
+			}
+		} else {
+			sel.target = get_sel_target;
+			if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
+				print_selection(sel);
+		}
+	}
+
 	if (options[OptGetInput]) {
 		if (doioctl(fd, VIDIOC_G_INPUT, &input) == 0) {
 			printf("Video input : %d", input);
--
1.7.4.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v1] v4l2-ctl: Add support for VIDIOC_G/S_SELECTION ioctls
  2012-07-22 20:42 [PATCH v1] v4l2-ctl: Add support for VIDIOC_G/S_SELECTION ioctls Sylwester Nawrocki
@ 2012-07-23  9:02 ` Hans Verkuil
  0 siblings, 0 replies; 2+ messages in thread
From: Hans Verkuil @ 2012-07-23  9:02 UTC (permalink / raw)
  To: Sylwester Nawrocki; +Cc: linux-media

On Sun July 22 2012 22:42:02 Sylwester Nawrocki wrote:
> This patch adds following commands for the selection API ioctls:
> 
> --get-selection, --set-selection,
> --get-selection-output, --set-selection-output.
> 
> All supported selection rectangles at a video node are now also
> displayed in case of --all command.

I've committed both patches. Thanks!

Regards,

	Hans

> 
> Signed-off-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
> ---
>  utils/v4l2-ctl/v4l2-ctl.cpp |  239 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 239 insertions(+), 0 deletions(-)
> 
> diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
> index 1a6c4ae..c70e88c 100644
> --- a/utils/v4l2-ctl/v4l2-ctl.cpp
> +++ b/utils/v4l2-ctl/v4l2-ctl.cpp
> @@ -139,6 +139,10 @@ enum Option {
>  	OptSetOverlayCrop,
>  	OptGetOutputOverlayCrop,
>  	OptSetOutputOverlayCrop,
> +	OptGetSelection,
> +	OptSetSelection,
> +	OptGetOutputSelection,
> +	OptSetOutputSelection,
>  	OptGetAudioInput,
>  	OptSetAudioInput,
>  	OptGetAudioOutput,
> @@ -233,6 +237,13 @@ static const flag_def service_def[] = {
>  #define CropLeft		(1L<<2)
>  #define CropTop 		(1L<<3)
> 
> +/* selection specified */
> +#define SelectionWidth		(1L<<0)
> +#define SelectionHeight		(1L<<1)
> +#define SelectionLeft		(1L<<2)
> +#define SelectionTop 		(1L<<3)
> +#define SelectionFlags 		(1L<<4)
> +
>  static struct option long_options[] = {
>  	{"list-audio-inputs", no_argument, 0, OptListAudioInputs},
>  	{"list-audio-outputs", no_argument, 0, OptListAudioOutputs},
> @@ -322,6 +333,10 @@ 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-selection", required_argument, 0, OptGetSelection},
> +	{"set-selection", required_argument, 0, OptSetSelection},
> +	{"get-selection-output", required_argument, 0, OptGetOutputSelection},
> +	{"set-selection-output", required_argument, 0, OptSetOutputSelection},
>  	{"get-jpeg-comp", no_argument, 0, OptGetJpegComp},
>  	{"set-jpeg-comp", required_argument, 0, OptSetJpegComp},
>  	{"get-modulator", no_argument, 0, OptGetModulator},
> @@ -631,6 +646,26 @@ static void usage_crop(void)
>  	       );
>  }
> 
> +static void usage_selection(void)
> +{
> +	printf("\nSelection options:\n"
> +	       "  --get-selection=target=<target>\n"
> +	       "                     query the video capture selection rectangle [VIDIOC_G_SELECTION]\n"
> +	       "                     See --set-selection command for the valid <target> values.\n"
> +	       "  --set-selection=target=<target>,flags=<flags>,top=<x>,left=<y>,width=<w>,height=<h>\n"
> +	       "                     set the video capture selection rectangle [VIDIOC_S_SELECTION]\n"
> +	       "                     target=crop|crop_bounds|crop_default|compose|compose_bounds|\n"
> +	       "                            compose_default|compose_padded\n"
> +	       "                     flags=le|ge\n"
> +	       "  --get-selection-output=target=<target>\n"
> +	       "                     query the video output selection rectangle [VIDIOC_G_SELECTION]\n"
> +	       "                     See --set-selection command for the valid <target> values.\n"
> +	       "  --set-selection-output=target=<target>,flags=<flags>,top=<x>,left=<y>,width=<w>,height=<h>\n"
> +	       "                     set the video output selection rectangle [VIDIOC_S_SELECTION]\n"
> +	       "                     See --set-selection command for the arguments.\n"
> +	       );
> +}
> +
>  static void usage_misc(void)
>  {
>  	printf("\nMiscellaneous options:\n"
> @@ -688,6 +723,7 @@ static void usage(void)
>  	usage_vidout();
>  	usage_overlay();
>  	usage_vbi();
> +	usage_selection();
>  	usage_crop();
>  	usage_misc();
>  }
> @@ -1267,6 +1303,35 @@ static void printcropcap(const struct v4l2_cropcap &cropcap)
>  	printf("\tPixel Aspect: %u/%u\n", cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator);
>  }
> 
> +static const flag_def selection_targets_def[] = {
> +	{ V4L2_SEL_TGT_CROP_ACTIVE, "crop" },
> +	{ V4L2_SEL_TGT_CROP_DEFAULT, "crop_default" },
> +	{ V4L2_SEL_TGT_CROP_BOUNDS, "crop_bounds" },
> +	{ V4L2_SEL_TGT_COMPOSE_ACTIVE, "compose" },
> +	{ V4L2_SEL_TGT_COMPOSE_DEFAULT, "compose_default" },
> +	{ V4L2_SEL_TGT_COMPOSE_BOUNDS, "compose_bounds" },
> +	{ V4L2_SEL_TGT_COMPOSE_PADDED, "compose_padded" },
> +	{ 0, NULL }
> +};
> +
> +static std::string seltarget2s(__u32 target)
> +{
> +	int i = 0;
> +
> +	while (selection_targets_def[i++].str != NULL) {
> +		if (selection_targets_def[i].flag == target)
> +			return selection_targets_def[i].str;
> +	}
> +	return "Unknown";
> +}
> +
> +static void print_selection(const struct v4l2_selection &sel)
> +{
> +	printf("Selection: %s, Left %d, Top %d, Width %d, Height %d\n",
> +			seltarget2s(sel.target).c_str(),
> +			sel.r.left, sel.r.top, sel.r.width, sel.r.height);
> +}
> +
>  static void printfmt(const struct v4l2_format &vfmt)
>  {
>  	const flag_def vbi_def[] = {
> @@ -2008,6 +2073,103 @@ static void parse_crop(char *optarg, unsigned int &set_crop, v4l2_rect &vcrop)
>  	}
>  }
> 
> +static void do_selection(int fd, unsigned int set_selection, struct v4l2_selection &vsel,
> +			 v4l2_buf_type type)
> +{
> +	struct v4l2_selection in_selection;
> +
> +	in_selection.type = type;
> +	in_selection.target = vsel.target;
> +
> +	if (doioctl(fd, VIDIOC_G_SELECTION, &in_selection) == 0) {
> +		if (set_selection & SelectionWidth)
> +			in_selection.r.width = vsel.r.width;
> +		if (set_selection & SelectionHeight)
> +			in_selection.r.height = vsel.r.height;
> +		if (set_selection & SelectionLeft)
> +			in_selection.r.left = vsel.r.left;
> +		if (set_selection & SelectionTop)
> +			in_selection.r.top = vsel.r.top;
> +		in_selection.flags = (set_selection & SelectionFlags) ? vsel.flags : 0;
> +		doioctl(fd, VIDIOC_S_SELECTION, &in_selection);
> +	}
> +}
> +
> +static int parse_selection_target(const char *s, unsigned int &target)
> +{
> +	if (!strcmp(s, "crop")) target = V4L2_SEL_TGT_CROP_ACTIVE;
> +	else if (!strcmp(s, "crop_default")) target = V4L2_SEL_TGT_CROP_DEFAULT;
> +	else if (!strcmp(s, "crop_bounds")) target = V4L2_SEL_TGT_CROP_BOUNDS;
> +	else if (!strcmp(s, "compose")) target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
> +	else if (!strcmp(s, "compose_default")) target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
> +	else if (!strcmp(s, "compose_bounds")) target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
> +	else if (!strcmp(s, "compose_padded")) target = V4L2_SEL_TGT_COMPOSE_PADDED;
> +	else return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int parse_selection_flags(const char *s)
> +{
> +	if (!strcmp(s, "le")) return V4L2_SEL_FLAG_LE;
> +	if (!strcmp(s, "ge")) return V4L2_SEL_FLAG_GE;
> +	return 0;
> +}
> +
> +static int parse_selection(char *optarg, unsigned int &set_sel, v4l2_selection &vsel)
> +{
> +	char *value;
> +	char *subs = optarg;
> +
> +	while (*subs != '\0') {
> +		static const char *const subopts[] = {
> +			"target",
> +			"flags",
> +			"left",
> +			"top",
> +			"width",
> +			"height",
> +			NULL
> +		};
> +
> +		switch (parse_subopt(&subs, subopts, &value)) {
> +		case 0:
> +			if (parse_selection_target(value, vsel.target)) {
> +				fprintf(stderr, "Unknown selection target\n");
> +				usage_selection();
> +				exit(1);
> +			}
> +			break;
> +		case 1:
> +			vsel.flags = parse_selection_flags(value);
> +			set_sel |= SelectionFlags;
> +			break;
> +		case 2:
> +			vsel.r.left = strtol(value, 0L, 0);
> +			set_sel |= SelectionLeft;
> +			break;
> +		case 3:
> +			vsel.r.top = strtol(value, 0L, 0);
> +			set_sel |= SelectionTop;
> +			break;
> +		case 4:
> +			vsel.r.width = strtol(value, 0L, 0);
> +			set_sel |= SelectionWidth;
> +			break;
> +		case 5:
> +			vsel.r.height = strtol(value, 0L, 0);
> +			set_sel |= SelectionHeight;
> +			break;
> +		default:
> +			fprintf(stderr, "Unknown option\n");
> +			usage_selection();
> +			exit(1);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static void parse_freq_seek(char *optarg, struct v4l2_hw_freq_seek &seek)
>  {
>  	char *value;
> @@ -2323,6 +2485,9 @@ int main(int argc, char **argv)
>  	unsigned int set_crop_out = 0;
>  	unsigned int set_crop_overlay = 0;
>  	unsigned int set_crop_out_overlay = 0;
> +	unsigned int set_selection = 0;
> +	unsigned int set_selection_out = 0;
> +	int get_sel_target = 0;
>  	unsigned int set_fbuf = 0;
>  	unsigned int set_overlay_fmt = 0;
>  	unsigned int set_overlay_fmt_out = 0;
> @@ -2353,6 +2518,8 @@ int main(int argc, char **argv)
>  	struct v4l2_rect vcrop_out; 	/* crop rect */
>  	struct v4l2_rect vcrop_overlay; 	/* crop rect */
>  	struct v4l2_rect vcrop_out_overlay; 	/* crop rect */
> +	struct v4l2_selection vselection; 	/* capture selection */
> +	struct v4l2_selection vselection_out;	/* output selection */
>  	struct v4l2_framebuffer fbuf;   /* fbuf */
>  	struct v4l2_jpegcompression jpegcomp; /* jpeg compression */
>  	struct v4l2_streamparm parm;	/* get/set parm */
> @@ -2409,6 +2576,8 @@ int main(int argc, char **argv)
>  	memset(&vcrop_out, 0, sizeof(vcrop_out));
>  	memset(&vcrop_overlay, 0, sizeof(vcrop_overlay));
>  	memset(&vcrop_out_overlay, 0, sizeof(vcrop_out_overlay));
> +	memset(&vselection, 0, sizeof(vselection));
> +	memset(&vselection_out, 0, sizeof(vselection_out));
>  	memset(&vf, 0, sizeof(vf));
>  	memset(&vs, 0, sizeof(vs));
>  	memset(&fbuf, 0, sizeof(fbuf));
> @@ -2694,6 +2863,25 @@ int main(int argc, char **argv)
>  		case OptSetOutputOverlayCrop:
>  			parse_crop(optarg, set_crop_out_overlay, vcrop_out_overlay);
>  			break;
> +		case OptSetSelection:
> +			parse_selection(optarg, set_selection, vselection);
> +			break;
> +		case OptSetOutputSelection:
> +			parse_selection(optarg, set_selection_out, vselection_out);
> +			break;
> +		case OptGetOutputSelection:
> +		case OptGetSelection: {
> +			struct v4l2_selection gsel;
> +			unsigned int get_sel;
> +
> +			if (parse_selection(optarg, get_sel, gsel)) {
> +				fprintf(stderr, "Unknown selection target\n");
> +				usage_selection();
> +				exit(1);
> +			}
> +			get_sel_target = gsel.target;
> +			break;
> +		}
>  		case OptSetInput:
>  			input = strtol(optarg, 0L, 0);
>  			break;
> @@ -3097,6 +3285,9 @@ int main(int argc, char **argv)
>  		options[OptGetDvTimings] = 1;
>  		options[OptGetDvTimingsCap] = 1;
>  		options[OptGetPriority] = 1;
> +		options[OptGetSelection] = 1;
> +		options[OptGetOutputSelection] = 1;
> +		get_sel_target = -1;
>  		options[OptSilent] = 1;
>  	}
> 
> @@ -3489,6 +3680,14 @@ int main(int argc, char **argv)
>  		do_crop(fd, set_crop_out_overlay, vcrop_out_overlay, V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY);
>  	}
> 
> +	if (options[OptSetSelection]) {
> +		do_selection(fd, set_selection, vselection, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	}
> +
> +	if (options[OptSetOutputSelection]) {
> +		do_selection(fd, set_selection_out, vselection_out, V4L2_BUF_TYPE_VIDEO_OUTPUT);
> +	}
> +
>  	if (options[OptSetCtrl] && !set_ctrls.empty()) {
>  		struct v4l2_ext_controls ctrls;
>  		class2ctrls_map class2ctrls;
> @@ -3720,6 +3919,46 @@ int main(int argc, char **argv)
>  			printcrop(crop);
>  	}
> 
> +	if (options[OptGetSelection]) {
> +		struct v4l2_selection sel;
> +		int t = 0;
> +
> +		memset(&sel, 0, sizeof(sel));
> +		sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +
> +		if (get_sel_target == -1) {
> +			while (selection_targets_def[t++].str != NULL) {
> +				sel.target = selection_targets_def[t].flag;
> +				if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
> +					print_selection(sel);
> +			}
> +		} else {
> +			sel.target = get_sel_target;
> +			if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
> +				print_selection(sel);
> +		}
> +	}
> +
> +	if (options[OptGetOutputSelection]) {
> +		struct v4l2_selection sel;
> +		int t = 0;
> +
> +		memset(&sel, 0, sizeof(sel));
> +		sel.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
> +
> +		if (get_sel_target == -1) {
> +			while (selection_targets_def[t++].str != NULL) {
> +				sel.target = selection_targets_def[t].flag;
> +				if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
> +					print_selection(sel);
> +			}
> +		} else {
> +			sel.target = get_sel_target;
> +			if (doioctl(fd, VIDIOC_G_SELECTION, &sel) == 0)
> +				print_selection(sel);
> +		}
> +	}
> +
>  	if (options[OptGetInput]) {
>  		if (doioctl(fd, VIDIOC_G_INPUT, &input) == 0) {
>  			printf("Video input : %d", input);
> --
> 1.7.4.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-07-23  9:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-22 20:42 [PATCH v1] v4l2-ctl: Add support for VIDIOC_G/S_SELECTION ioctls Sylwester Nawrocki
2012-07-23  9:02 ` Hans Verkuil

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.