aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@maxwell.research.nokia.com>2011-02-18 07:41:51 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-04-17 06:41:19 -0400
commit8dc1e75e9dc2fa3f5fa2e98be670118366beac92 (patch)
treea19233decf3db99a9abb827f5ddc0bcfbbd6bc6d /drivers/media
parentf792e4f6ac12d45b0eca12f505295c48182a8fd2 (diff)
[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: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
index 40b2db873a1..70897ce5dce 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -714,16 +714,36 @@ static void resizer_print_status(struct isp_res_device *res)
714 * iw and ih are the input width and height after cropping. Those equations need 714 * iw and ih are the input width and height after cropping. Those equations need
715 * to be satisfied exactly for the resizer to work correctly. 715 * to be satisfied exactly for the resizer to work correctly.
716 * 716 *
717 * Reverting the equations, we can compute the resizing ratios with 717 * The equations can't be easily reverted, as the >> 8 operation is not linear.
718 * In addition, not all input sizes can be achieved for a given output size. To
719 * get the highest input size lower than or equal to the requested input size,
720 * we need to compute the highest resizing ratio that satisfies the following
721 * inequality (taking the 4-tap mode width equation as an example)
722 *
723 * iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7
724 *
725 * (where iw is the requested input width) which can be rewritten as
726 *
727 * iw - 7 >= (32 * sph + (ow - 1) * hrsz + 16) >> 8
728 * (iw - 7) << 8 >= 32 * sph + (ow - 1) * hrsz + 16 - b
729 * ((iw - 7) << 8) + b >= 32 * sph + (ow - 1) * hrsz + 16
730 *
731 * where b is the value of the 8 least significant bits of the right hand side
732 * expression of the last inequality. The highest resizing ratio value will be
733 * achieved when b is equal to its maximum value of 255. That resizing ratio
734 * value will still satisfy the original inequality, as b will disappear when
735 * the expression will be shifted right by 8.
736 *
737 * The reverted the equations thus become
718 * 738 *
719 * - 8-phase, 4-tap mode 739 * - 8-phase, 4-tap mode
720 * hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1) 740 * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1)
721 * vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1) 741 * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1)
722 * - 4-phase, 7-tap mode 742 * - 4-phase, 7-tap mode
723 * hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1) 743 * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1)
724 * vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1) 744 * vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1)
725 * 745 *
726 * The ratios are integer values, and must be rounded down to ensure that the 746 * The ratios are integer values, and are rounded down to ensure that the
727 * cropped input size is not bigger than the uncropped input size. 747 * cropped input size is not bigger than the uncropped input size.
728 * 748 *
729 * As the number of phases/taps, used to select the correct equations to compute 749 * 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 max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT); 819 max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
800 output->height = clamp(output->height, min_height, max_height); 820 output->height = clamp(output->height, min_height, max_height);
801 821
802 ratio->vert = ((input->height - 4) * 256 - 16 - 32 * spv) 822 ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv)
803 / (output->height - 1); 823 / (output->height - 1);
804 if (ratio->vert > MID_RESIZE_VALUE) 824 if (ratio->vert > MID_RESIZE_VALUE)
805 ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv) 825 ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv)
806 / (output->height - 1); 826 / (output->height - 1);
807 ratio->vert = clamp_t(unsigned int, ratio->vert, 827 ratio->vert = clamp_t(unsigned int, ratio->vert,
808 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); 828 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
@@ -870,10 +890,10 @@ static void resizer_calc_ratios(struct isp_res_device *res,
870 max_width & ~(width_alignment - 1)); 890 max_width & ~(width_alignment - 1));
871 output->width = ALIGN(output->width, width_alignment); 891 output->width = ALIGN(output->width, width_alignment);
872 892
873 ratio->horz = ((input->width - 7) * 256 - 16 - 32 * sph) 893 ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph)
874 / (output->width - 1); 894 / (output->width - 1);
875 if (ratio->horz > MID_RESIZE_VALUE) 895 if (ratio->horz > MID_RESIZE_VALUE)
876 ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph) 896 ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph)
877 / (output->width - 1); 897 / (output->width - 1);
878 ratio->horz = clamp_t(unsigned int, ratio->horz, 898 ratio->horz = clamp_t(unsigned int, ratio->horz,
879 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); 899 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);