atomisp: enable upscaling on ISP
authorTuukka Toivonen <tuukka.toivonen@intel.com>
Wed, 13 Jun 2012 08:17:01 +0000 (11:17 +0300)
committerbuildbot <buildbot@intel.com>
Wed, 20 Jun 2012 13:50:13 +0000 (06:50 -0700)
BZ: 41720

If the requested resolution is bigger than what the sensor supports,
use ISP upscaler to construct image of desired size instead of
returning a smaller resolution to user space.

Change-Id: Ie7b9e55fbe28b38b976851008f03537456501d26
Signed-off-by: Tuukka Toivonen <tuukka.toivonen@intel.com>
Reviewed-on: http://android.intel.com:8080/52729
Reviewed-by: Laakso, Antti <antti.laakso@intel.com>
Reviewed-by: Koski, Anttu <anttu.koski@intel.com>
Tested-by: Koski, Anttu <anttu.koski@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/media/video/atomisp/atomisp_cmd.c
drivers/media/video/atomisp/atomisp_fops.c
drivers/media/video/atomisp/include/atomisp/atomisp_internal.h

index c9a47db..46b24e1 100644 (file)
@@ -2762,7 +2762,7 @@ int atomisp_get_fmt(struct video_device *vdev, struct v4l2_format *f)
 
 /* This function looks up the closest available resolution. */
 int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f,
-                                               bool *res_overflow)
+                   bool *upscaling)
 {
        struct atomisp_device *isp = video_get_drvdata(vdev);
        struct v4l2_mbus_framefmt snr_mbus_fmt;
@@ -2820,16 +2820,6 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f,
                        f->fmt.pix.pixelformat = fmt->pixelformat;
        }
 
-       if ((in_width < out_width) && (in_height < out_height)) {
-               out_width = in_width;
-               out_height = in_height;
-               /* Set the flag when resolution requested is
-                * beyond the max value supported by sensor
-                */
-               if (res_overflow != NULL)
-                       *res_overflow = true;
-       }
-
        /* app vs isp */
        out_width = min_t(u32, out_width, ATOM_ISP_MAX_WIDTH);
        out_height = min_t(u32, out_height, ATOM_ISP_MAX_HEIGHT);
@@ -2840,6 +2830,12 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f,
        out_width = out_width - out_width % ATOM_ISP_STEP_WIDTH;
        out_height = out_height - out_height % ATOM_ISP_STEP_HEIGHT;
 
+       /* Enable upscaling when the resolution requested is
+        * beyond the max value supported by sensor
+        */
+       if (upscaling)
+               *upscaling = in_width < out_width && in_height < out_height;
+
        f->fmt.pix.width = out_width;
        f->fmt.pix.height = out_height;
 
@@ -3096,15 +3092,16 @@ static int atomisp_get_effective_resolution(struct atomisp_device *isp,
        format = get_atomisp_format_bridge(pixelformat);
        if (format == NULL)
                return -EINVAL;
-       if (!isp->params.yuv_ds_en) {
+       if (!isp->params.yuv_ds_en && !isp->params.yuv_us_en) {
                in_fmt->width = out_width;
                in_fmt->height = out_height;
                return 0;
        }
        no_padding_w = out_fmt->width - padding_w;
        no_padding_h = out_fmt->height - padding_h;
-       /* enable YUV downscaling automatically */
-       if (no_padding_w > out_width || no_padding_h > out_height) {
+       /* Check if we need scaling */
+       if (no_padding_w > out_width || no_padding_h > out_height
+           || isp->params.yuv_us_en) {
                /* keep a right ratio of width and height*/
                in_fmt->width = no_padding_w;
                in_fmt->height = DIV_RND_UP(in_fmt->width * out_height,
@@ -3264,7 +3261,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
                     dvs_env_h = 0;
        unsigned int padding_w = pad_w,
                     padding_h = pad_h;
-       bool res_overflow = false;
        struct v4l2_streamparm sensor_parm;
        int ret;
 
@@ -3353,7 +3349,7 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
 
        /* get sensor resolution and format */
        snr_fmt = *f;
-       atomisp_try_fmt(vdev, &snr_fmt, &res_overflow);
+       atomisp_try_fmt(vdev, &snr_fmt, &isp->params.yuv_us_en);
        width = snr_fmt.fmt.pix.width;
        height = snr_fmt.fmt.pix.height;
 
@@ -3370,24 +3366,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
        } else
                isp->sw_contex.bypass = false;
 
-       /* construct resolution supported by isp */
-       if (res_overflow) {
-               width -= padding_w;
-               height -= padding_h;
-               /* app vs isp */
-               width = min_t(u32, width, ATOM_ISP_MAX_WIDTH);
-               height = min_t(u32, height, ATOM_ISP_MAX_HEIGHT);
-
-               width = max_t(u32, width, ATOM_ISP_MIN_WIDTH);
-               height = max_t(u32, height, ATOM_ISP_MIN_HEIGHT);
-
-               width = width - width % ATOM_ISP_STEP_WIDTH;
-               height = height - height % ATOM_ISP_STEP_HEIGHT;
-
-               f->fmt.pix.width = width;
-               f->fmt.pix.height = height;
-       }
-
        /* set dis envelop if video and dis are enabled */
        atomisp_set_dis_envelop(isp, width, height, &dvs_env_w, &dvs_env_h);
 
index 2d2fbd3..c6f3ab5 100644 (file)
@@ -240,7 +240,8 @@ int atomisp_init_struct(struct atomisp_device *isp)
        isp->params.xnr_en = 0;
        isp->params.false_color = 0;
        isp->params.online_process = 1;
-       isp->params.yuv_ds_en = 0;
+       isp->params.yuv_ds_en = false;
+       isp->params.yuv_us_en = false;
        isp->params.vf_overlay = NULL;
        isp->sw_contex.sensor_streaming = false;
        isp->sw_contex.isp_streaming = false;
index 9219a85..8ab3cb5 100644 (file)
@@ -169,7 +169,8 @@ struct atomisp_sw_contex {
 
 struct atomisp_css_params {
        int online_process;
-       int yuv_ds_en;
+       bool yuv_ds_en;                         /* Enable YUV downscaling */
+       bool yuv_us_en;                         /* Enable YUV upscaling */
        unsigned int color_effect;
        bool gdc_cac_en;
        bool macc_en;