* [PATCH] mt9t031: preserve output format on VIDIOC_S_CROP
@ 2010-04-14 14:23 Guennadi Liakhovetski
2010-04-22 8:50 ` Guennadi Liakhovetski
0 siblings, 1 reply; 4+ messages in thread
From: Guennadi Liakhovetski @ 2010-04-14 14:23 UTC (permalink / raw)
To: Linux Media Mailing List; +Cc: Valentin Longchamp
Interpretation of the V4L2 API specification, according to which the
VIDIOC_S_CROP ioctl for capture devices shall set the input window and
preserve the scales, thus possibly changing the output window, seems to be
incorrect. Switch to using a more intuitive definition, i.e., to
preserving the output format while changing scales.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
Val, I do not have any mt9t031 hardware any more, could you, please, test
this patch and verify, that it does indeed do, what's described above?
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index a9061bf..a604fa0 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -63,6 +63,8 @@
struct mt9t031 {
struct v4l2_subdev subdev;
struct v4l2_rect rect; /* Sensor window */
+ unsigned int out_width;
+ unsigned int out_height;
int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
u16 xskip;
u16 yskip;
@@ -284,6 +286,26 @@ static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
return skip;
}
+static u16 mt9t031_skip_out(s32 *source, s32 *target)
+{
+ unsigned int skip;
+
+ if (*source < *target + *target / 2) {
+ *target = *source;
+ return 1;
+ }
+
+ skip = (*source + *target / 2) / *target;
+ if (skip > 8) {
+ skip = 8;
+ *target = (*source + 4) / 8;
+ }
+ /* We try to preserve input, but with division we have to adjust it too */
+ *source = *target * skip;
+
+ return skip;
+}
+
/* rect is the sensor rectangle, the caller guarantees parameter validity */
static int mt9t031_set_params(struct i2c_client *client,
struct v4l2_rect *rect, u16 xskip, u16 yskip)
@@ -393,6 +415,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
struct v4l2_rect rect = a->c;
struct i2c_client *client = sd->priv;
struct mt9t031 *mt9t031 = to_mt9t031(client);
+ u16 xskip, yskip;
rect.width = ALIGN(rect.width, 2);
rect.height = ALIGN(rect.height, 2);
@@ -403,7 +426,10 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
soc_camera_limit_side(&rect.top, &rect.height,
MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
- return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip);
+ xskip = mt9t031_skip_out(&rect.width, &mt9t031->out_width);
+ yskip = mt9t031_skip_out(&rect.height, &mt9t031->out_height);
+
+ return mt9t031_set_params(client, &rect, xskip, yskip);
}
static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
@@ -437,8 +463,8 @@ static int mt9t031_g_fmt(struct v4l2_subdev *sd,
struct i2c_client *client = sd->priv;
struct mt9t031 *mt9t031 = to_mt9t031(client);
- mf->width = mt9t031->rect.width / mt9t031->xskip;
- mf->height = mt9t031->rect.height / mt9t031->yskip;
+ mf->width = mt9t031->out_width;
+ mf->height = mt9t031->out_height;
mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
mf->colorspace = V4L2_COLORSPACE_SRGB;
mf->field = V4L2_FIELD_NONE;
@@ -455,8 +481,9 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
struct v4l2_rect rect = mt9t031->rect;
/*
- * try_fmt has put width and height within limits.
- * S_FMT: use binning and skipping for scaling
+ * try_fmt has put width and height within limits. Note: when converting
+ * to a generic v4l2-subdev driver, try_fmt will have to be called
+ * explicitly. S_FMT: use binning and skipping for scaling.
*/
xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH);
yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT);
@@ -464,6 +491,9 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
mf->colorspace = V4L2_COLORSPACE_SRGB;
+ mt9t031->out_width = mf->width;
+ mt9t031->out_height = mf->height;
+
/* mt9t031_set_params() doesn't change width and height */
return mt9t031_set_params(client, &rect, xskip, yskip);
}
@@ -807,6 +837,9 @@ static int mt9t031_probe(struct i2c_client *client,
mt9t031->rect.width = MT9T031_MAX_WIDTH;
mt9t031->rect.height = MT9T031_MAX_HEIGHT;
+ mt9t031->out_width = MT9T031_MAX_WIDTH;
+ mt9t031->out_height = MT9T031_MAX_HEIGHT;
+
/*
* Simulated autoexposure. If enabled, we calculate shutter width
* ourselves in the driver based on vertical blanking and frame width
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] mt9t031: preserve output format on VIDIOC_S_CROP
2010-04-14 14:23 [PATCH] mt9t031: preserve output format on VIDIOC_S_CROP Guennadi Liakhovetski
@ 2010-04-22 8:50 ` Guennadi Liakhovetski
2010-04-22 9:14 ` Valentin Longchamp
0 siblings, 1 reply; 4+ messages in thread
From: Guennadi Liakhovetski @ 2010-04-22 8:50 UTC (permalink / raw)
To: Linux Media Mailing List; +Cc: Valentin Longchamp
On Wed, 14 Apr 2010, Guennadi Liakhovetski wrote:
> Interpretation of the V4L2 API specification, according to which the
> VIDIOC_S_CROP ioctl for capture devices shall set the input window and
> preserve the scales, thus possibly changing the output window, seems to be
> incorrect. Switch to using a more intuitive definition, i.e., to
> preserving the output format while changing scales.
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
>
> Val, I do not have any mt9t031 hardware any more, could you, please, test
> this patch and verify, that it does indeed do, what's described above?
There hasn't been any replies to this, so, I presume, this patch cannot be
tested at present. Therefore I'm going to leave it out of my pull requests
until it gets tested somehow.
Thanks
Guennadi
>
> diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
> index a9061bf..a604fa0 100644
> --- a/drivers/media/video/mt9t031.c
> +++ b/drivers/media/video/mt9t031.c
> @@ -63,6 +63,8 @@
> struct mt9t031 {
> struct v4l2_subdev subdev;
> struct v4l2_rect rect; /* Sensor window */
> + unsigned int out_width;
> + unsigned int out_height;
> int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
> u16 xskip;
> u16 yskip;
> @@ -284,6 +286,26 @@ static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
> return skip;
> }
>
> +static u16 mt9t031_skip_out(s32 *source, s32 *target)
> +{
> + unsigned int skip;
> +
> + if (*source < *target + *target / 2) {
> + *target = *source;
> + return 1;
> + }
> +
> + skip = (*source + *target / 2) / *target;
> + if (skip > 8) {
> + skip = 8;
> + *target = (*source + 4) / 8;
> + }
> + /* We try to preserve input, but with division we have to adjust it too */
> + *source = *target * skip;
> +
> + return skip;
> +}
> +
> /* rect is the sensor rectangle, the caller guarantees parameter validity */
> static int mt9t031_set_params(struct i2c_client *client,
> struct v4l2_rect *rect, u16 xskip, u16 yskip)
> @@ -393,6 +415,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
> struct v4l2_rect rect = a->c;
> struct i2c_client *client = sd->priv;
> struct mt9t031 *mt9t031 = to_mt9t031(client);
> + u16 xskip, yskip;
>
> rect.width = ALIGN(rect.width, 2);
> rect.height = ALIGN(rect.height, 2);
> @@ -403,7 +426,10 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
> soc_camera_limit_side(&rect.top, &rect.height,
> MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
>
> - return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip);
> + xskip = mt9t031_skip_out(&rect.width, &mt9t031->out_width);
> + yskip = mt9t031_skip_out(&rect.height, &mt9t031->out_height);
> +
> + return mt9t031_set_params(client, &rect, xskip, yskip);
> }
>
> static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
> @@ -437,8 +463,8 @@ static int mt9t031_g_fmt(struct v4l2_subdev *sd,
> struct i2c_client *client = sd->priv;
> struct mt9t031 *mt9t031 = to_mt9t031(client);
>
> - mf->width = mt9t031->rect.width / mt9t031->xskip;
> - mf->height = mt9t031->rect.height / mt9t031->yskip;
> + mf->width = mt9t031->out_width;
> + mf->height = mt9t031->out_height;
> mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
> mf->colorspace = V4L2_COLORSPACE_SRGB;
> mf->field = V4L2_FIELD_NONE;
> @@ -455,8 +481,9 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
> struct v4l2_rect rect = mt9t031->rect;
>
> /*
> - * try_fmt has put width and height within limits.
> - * S_FMT: use binning and skipping for scaling
> + * try_fmt has put width and height within limits. Note: when converting
> + * to a generic v4l2-subdev driver, try_fmt will have to be called
> + * explicitly. S_FMT: use binning and skipping for scaling.
> */
> xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH);
> yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT);
> @@ -464,6 +491,9 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
> mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
> mf->colorspace = V4L2_COLORSPACE_SRGB;
>
> + mt9t031->out_width = mf->width;
> + mt9t031->out_height = mf->height;
> +
> /* mt9t031_set_params() doesn't change width and height */
> return mt9t031_set_params(client, &rect, xskip, yskip);
> }
> @@ -807,6 +837,9 @@ static int mt9t031_probe(struct i2c_client *client,
> mt9t031->rect.width = MT9T031_MAX_WIDTH;
> mt9t031->rect.height = MT9T031_MAX_HEIGHT;
>
> + mt9t031->out_width = MT9T031_MAX_WIDTH;
> + mt9t031->out_height = MT9T031_MAX_HEIGHT;
> +
> /*
> * Simulated autoexposure. If enabled, we calculate shutter width
> * ourselves in the driver based on vertical blanking and frame width
>
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] mt9t031: preserve output format on VIDIOC_S_CROP
2010-04-22 8:50 ` Guennadi Liakhovetski
@ 2010-04-22 9:14 ` Valentin Longchamp
2010-04-22 9:31 ` Guennadi Liakhovetski
0 siblings, 1 reply; 4+ messages in thread
From: Valentin Longchamp @ 2010-04-22 9:14 UTC (permalink / raw)
To: Guennadi Liakhovetski; +Cc: Linux Media Mailing List
Guennadi Liakhovetski wrote:
> On Wed, 14 Apr 2010, Guennadi Liakhovetski wrote:
>
>> Interpretation of the V4L2 API specification, according to which the
>> VIDIOC_S_CROP ioctl for capture devices shall set the input window and
>> preserve the scales, thus possibly changing the output window, seems to be
>> incorrect. Switch to using a more intuitive definition, i.e., to
>> preserving the output format while changing scales.
>>
>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>> ---
>>
>> Val, I do not have any mt9t031 hardware any more, could you, please, test
>> this patch and verify, that it does indeed do, what's described above?
>
> There hasn't been any replies to this, so, I presume, this patch cannot be
> tested at present. Therefore I'm going to leave it out of my pull requests
> until it gets tested somehow.
Sorry Guennadi, the testing is on my todo-list, but I am getting nearer
to the end of my thesis and I really am very busy at the moment. I hope
I can give it a spin on a mt9t031 in the coming weeks.
Val
>
> Thanks
> Guennadi
>
>> diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
>> index a9061bf..a604fa0 100644
>> --- a/drivers/media/video/mt9t031.c
>> +++ b/drivers/media/video/mt9t031.c
>> @@ -63,6 +63,8 @@
>> struct mt9t031 {
>> struct v4l2_subdev subdev;
>> struct v4l2_rect rect; /* Sensor window */
>> + unsigned int out_width;
>> + unsigned int out_height;
>> int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
>> u16 xskip;
>> u16 yskip;
>> @@ -284,6 +286,26 @@ static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
>> return skip;
>> }
>>
>> +static u16 mt9t031_skip_out(s32 *source, s32 *target)
>> +{
>> + unsigned int skip;
>> +
>> + if (*source < *target + *target / 2) {
>> + *target = *source;
>> + return 1;
>> + }
>> +
>> + skip = (*source + *target / 2) / *target;
>> + if (skip > 8) {
>> + skip = 8;
>> + *target = (*source + 4) / 8;
>> + }
>> + /* We try to preserve input, but with division we have to adjust it too */
>> + *source = *target * skip;
>> +
>> + return skip;
>> +}
>> +
>> /* rect is the sensor rectangle, the caller guarantees parameter validity */
>> static int mt9t031_set_params(struct i2c_client *client,
>> struct v4l2_rect *rect, u16 xskip, u16 yskip)
>> @@ -393,6 +415,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
>> struct v4l2_rect rect = a->c;
>> struct i2c_client *client = sd->priv;
>> struct mt9t031 *mt9t031 = to_mt9t031(client);
>> + u16 xskip, yskip;
>>
>> rect.width = ALIGN(rect.width, 2);
>> rect.height = ALIGN(rect.height, 2);
>> @@ -403,7 +426,10 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
>> soc_camera_limit_side(&rect.top, &rect.height,
>> MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
>>
>> - return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip);
>> + xskip = mt9t031_skip_out(&rect.width, &mt9t031->out_width);
>> + yskip = mt9t031_skip_out(&rect.height, &mt9t031->out_height);
>> +
>> + return mt9t031_set_params(client, &rect, xskip, yskip);
>> }
>>
>> static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
>> @@ -437,8 +463,8 @@ static int mt9t031_g_fmt(struct v4l2_subdev *sd,
>> struct i2c_client *client = sd->priv;
>> struct mt9t031 *mt9t031 = to_mt9t031(client);
>>
>> - mf->width = mt9t031->rect.width / mt9t031->xskip;
>> - mf->height = mt9t031->rect.height / mt9t031->yskip;
>> + mf->width = mt9t031->out_width;
>> + mf->height = mt9t031->out_height;
>> mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
>> mf->colorspace = V4L2_COLORSPACE_SRGB;
>> mf->field = V4L2_FIELD_NONE;
>> @@ -455,8 +481,9 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
>> struct v4l2_rect rect = mt9t031->rect;
>>
>> /*
>> - * try_fmt has put width and height within limits.
>> - * S_FMT: use binning and skipping for scaling
>> + * try_fmt has put width and height within limits. Note: when converting
>> + * to a generic v4l2-subdev driver, try_fmt will have to be called
>> + * explicitly. S_FMT: use binning and skipping for scaling.
>> */
>> xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH);
>> yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT);
>> @@ -464,6 +491,9 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd,
>> mf->code = V4L2_MBUS_FMT_SBGGR10_1X10;
>> mf->colorspace = V4L2_COLORSPACE_SRGB;
>>
>> + mt9t031->out_width = mf->width;
>> + mt9t031->out_height = mf->height;
>> +
>> /* mt9t031_set_params() doesn't change width and height */
>> return mt9t031_set_params(client, &rect, xskip, yskip);
>> }
>> @@ -807,6 +837,9 @@ static int mt9t031_probe(struct i2c_client *client,
>> mt9t031->rect.width = MT9T031_MAX_WIDTH;
>> mt9t031->rect.height = MT9T031_MAX_HEIGHT;
>>
>> + mt9t031->out_width = MT9T031_MAX_WIDTH;
>> + mt9t031->out_height = MT9T031_MAX_HEIGHT;
>> +
>> /*
>> * Simulated autoexposure. If enabled, we calculate shutter width
>> * ourselves in the driver based on vertical blanking and frame width
>>
>
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
--
Valentin Longchamp, PhD Student, EPFL-STI-LSRO1
valentin.longchamp@epfl.ch, Phone: +41216937827
http://people.epfl.ch/valentin.longchamp
MEB3494, Station 9, CH-1015 Lausanne
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] mt9t031: preserve output format on VIDIOC_S_CROP
2010-04-22 9:14 ` Valentin Longchamp
@ 2010-04-22 9:31 ` Guennadi Liakhovetski
0 siblings, 0 replies; 4+ messages in thread
From: Guennadi Liakhovetski @ 2010-04-22 9:31 UTC (permalink / raw)
To: Valentin Longchamp; +Cc: Linux Media Mailing List
On Thu, 22 Apr 2010, Valentin Longchamp wrote:
> Guennadi Liakhovetski wrote:
> > On Wed, 14 Apr 2010, Guennadi Liakhovetski wrote:
> >
> > > Interpretation of the V4L2 API specification, according to which the
> > > VIDIOC_S_CROP ioctl for capture devices shall set the input window and
> > > preserve the scales, thus possibly changing the output window, seems to be
> > > incorrect. Switch to using a more intuitive definition, i.e., to
> > > preserving the output format while changing scales.
> > >
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > > ---
> > >
> > > Val, I do not have any mt9t031 hardware any more, could you, please, test
> > > this patch and verify, that it does indeed do, what's described above?
> >
> > There hasn't been any replies to this, so, I presume, this patch cannot be
> > tested at present. Therefore I'm going to leave it out of my pull requests
> > until it gets tested somehow.
>
> Sorry Guennadi, the testing is on my todo-list, but I am getting nearer to the
> end of my thesis and I really am very busy at the moment. I hope I can give it
> a spin on a mt9t031 in the coming weeks.
Np, we can push it out with the next development cycle, noone is
complaining, so, noone actually has a problem with the present version
either, I just would prefer to get it fixed, but it's not urgent.
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-04-22 9:31 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-14 14:23 [PATCH] mt9t031: preserve output format on VIDIOC_S_CROP Guennadi Liakhovetski
2010-04-22 8:50 ` Guennadi Liakhovetski
2010-04-22 9:14 ` Valentin Longchamp
2010-04-22 9:31 ` Guennadi Liakhovetski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox