mirror of https://gitee.com/openkylin/linux.git
[media] v4l2-dv-timings: fix overflow in gtf timings calculation
The intermediate calculation in the expression for hblank can exceed 32 bit signed range. This overflow can lead to negative values for hblank. Typecasting intermediate variable to higher precision. Cc: Martin Bugge <marbugge@cisco.com> Signed-off-by: Prashant Laddha <prladdha@cisco.com> [hans.verkuil@cisco.com: made the denominator u32, since that's what div_u64 expects] Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
ed1bc664da
commit
c9bc9f5075
|
@ -25,6 +25,7 @@
|
|||
#include <linux/videodev2.h>
|
||||
#include <linux/v4l2-dv-timings.h>
|
||||
#include <media/v4l2-dv-timings.h>
|
||||
#include <linux/math64.h>
|
||||
|
||||
MODULE_AUTHOR("Hans Verkuil");
|
||||
MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
|
||||
|
@ -554,16 +555,23 @@ bool v4l2_detect_gtf(unsigned frame_height,
|
|||
image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1);
|
||||
|
||||
/* Horizontal */
|
||||
if (default_gtf)
|
||||
h_blank = ((image_width * GTF_D_C_PRIME * hfreq) -
|
||||
(image_width * GTF_D_M_PRIME * 1000) +
|
||||
(hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) / 2) /
|
||||
(hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000);
|
||||
else
|
||||
h_blank = ((image_width * GTF_S_C_PRIME * hfreq) -
|
||||
(image_width * GTF_S_M_PRIME * 1000) +
|
||||
(hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) / 2) /
|
||||
(hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000);
|
||||
if (default_gtf) {
|
||||
u64 num;
|
||||
u32 den;
|
||||
|
||||
num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) -
|
||||
((u64)image_width * GTF_D_M_PRIME * 1000));
|
||||
den = hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000;
|
||||
h_blank = div_u64((num + (den >> 1)), den);
|
||||
} else {
|
||||
u64 num;
|
||||
u32 den;
|
||||
|
||||
num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) -
|
||||
((u64)image_width * GTF_S_M_PRIME * 1000));
|
||||
den = hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000;
|
||||
h_blank = div_u64((num + (den >> 1)), den);
|
||||
}
|
||||
|
||||
h_blank = ((h_blank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN)) *
|
||||
(2 * GTF_CELL_GRAN);
|
||||
|
|
Loading…
Reference in New Issue