Commit 8dc1e75e authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

[media] omap3isp: resizer: Improved resizer rsz factor formula

Round properly the rsz factor so that we get highest rsz so that the input
width (or height) is highest possible smaller or equal to what the user
asks.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent f792e4f6
...@@ -714,16 +714,36 @@ static void resizer_print_status(struct isp_res_device *res) ...@@ -714,16 +714,36 @@ static void resizer_print_status(struct isp_res_device *res)
* iw and ih are the input width and height after cropping. Those equations need * iw and ih are the input width and height after cropping. Those equations need
* to be satisfied exactly for the resizer to work correctly. * to be satisfied exactly for the resizer to work correctly.
* *
* Reverting the equations, we can compute the resizing ratios with * The equations can't be easily reverted, as the >> 8 operation is not linear.
* In addition, not all input sizes can be achieved for a given output size. To
* get the highest input size lower than or equal to the requested input size,
* we need to compute the highest resizing ratio that satisfies the following
* inequality (taking the 4-tap mode width equation as an example)
*
* iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7
*
* (where iw is the requested input width) which can be rewritten as
*
* iw - 7 >= (32 * sph + (ow - 1) * hrsz + 16) >> 8
* (iw - 7) << 8 >= 32 * sph + (ow - 1) * hrsz + 16 - b
* ((iw - 7) << 8) + b >= 32 * sph + (ow - 1) * hrsz + 16
*
* where b is the value of the 8 least significant bits of the right hand side
* expression of the last inequality. The highest resizing ratio value will be
* achieved when b is equal to its maximum value of 255. That resizing ratio
* value will still satisfy the original inequality, as b will disappear when
* the expression will be shifted right by 8.
*
* The reverted the equations thus become
* *
* - 8-phase, 4-tap mode * - 8-phase, 4-tap mode
* hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1) * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1)
* vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1) * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1)
* - 4-phase, 7-tap mode * - 4-phase, 7-tap mode
* hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1) * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1)
* vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1) * vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1)
* *
* The ratios are integer values, and must be rounded down to ensure that the * The ratios are integer values, and are rounded down to ensure that the
* cropped input size is not bigger than the uncropped input size. * cropped input size is not bigger than the uncropped input size.
* *
* As the number of phases/taps, used to select the correct equations to compute * As the number of phases/taps, used to select the correct equations to compute
...@@ -799,10 +819,10 @@ static void resizer_calc_ratios(struct isp_res_device *res, ...@@ -799,10 +819,10 @@ static void resizer_calc_ratios(struct isp_res_device *res,
max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT); max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
output->height = clamp(output->height, min_height, max_height); output->height = clamp(output->height, min_height, max_height);
ratio->vert = ((input->height - 4) * 256 - 16 - 32 * spv) ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv)
/ (output->height - 1); / (output->height - 1);
if (ratio->vert > MID_RESIZE_VALUE) if (ratio->vert > MID_RESIZE_VALUE)
ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv) ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv)
/ (output->height - 1); / (output->height - 1);
ratio->vert = clamp_t(unsigned int, ratio->vert, ratio->vert = clamp_t(unsigned int, ratio->vert,
MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
...@@ -870,10 +890,10 @@ static void resizer_calc_ratios(struct isp_res_device *res, ...@@ -870,10 +890,10 @@ static void resizer_calc_ratios(struct isp_res_device *res,
max_width & ~(width_alignment - 1)); max_width & ~(width_alignment - 1));
output->width = ALIGN(output->width, width_alignment); output->width = ALIGN(output->width, width_alignment);
ratio->horz = ((input->width - 7) * 256 - 16 - 32 * sph) ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph)
/ (output->width - 1); / (output->width - 1);
if (ratio->horz > MID_RESIZE_VALUE) if (ratio->horz > MID_RESIZE_VALUE)
ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph) ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph)
/ (output->width - 1); / (output->width - 1);
ratio->horz = clamp_t(unsigned int, ratio->horz, ratio->horz = clamp_t(unsigned int, ratio->horz,
MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment