diff options
Diffstat (limited to 'drivers/media/video/omap3isp/ispresizer.c')
-rw-r--r-- | drivers/media/video/omap3isp/ispresizer.c | 40 |
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); |