aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap3isp/ispresizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/omap3isp/ispresizer.c')
-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);