vpp: use new interface to increase accuracy of ar calculation [1/2]

PD#OTT-2068

Problem:
When playing 1280x128 video under normal screen mode, the aspect ratio from
decodec is not accurate enough by multipling 0x100. (128x256/1280=25.6).
Dropping 0.6 will cause height losing 9 lines.

Solution:
Using new interface to pass real ar width and height following steps:
1.Set old ar variable to 0x3ff as a trigger flag.
2.set the original ar value into sar_width and sar_height of vframe

Verify:
verified on franklin

Change-Id: I8a794edd968a76f198ee9cb168a7cfb858c858f8
Signed-off-by: Brian Zhu <brian.zhu@amlogic.com>
This commit is contained in:
Brian Zhu
2019-04-11 16:16:35 +08:00
committed by Tao Zeng
parent a3b88dbcca
commit c0e00133bc
2 changed files with 77 additions and 15 deletions

View File

@@ -597,6 +597,10 @@ static unsigned int custom_ar;
MODULE_PARM_DESC(custom_ar, "custom_ar");
module_param(custom_ar, uint, 0664);
static unsigned int force_use_ext_ar;
MODULE_PARM_DESC(force_use_ext_ar, "force_use_ext_ar");
module_param(force_use_ext_ar, uint, 0664);
static unsigned int force_no_compress;
MODULE_PARM_DESC(force_no_compress, "force_no_compress");
module_param(force_no_compress, uint, 0664);
@@ -867,7 +871,7 @@ static int vpp_set_filters_internal(
u32 width_out = wid_out; /* vinfo->width; */
u32 height_out = hei_out; /* vinfo->height; */
u32 aspect_ratio_out =
(vinfo->aspect_ratio_den << 8) / vinfo->aspect_ratio_num;
(vinfo->aspect_ratio_den << 10) / vinfo->aspect_ratio_num;
bool fill_match = true;
u32 orig_aspect = 0;
u32 screen_aspect = 0;
@@ -890,6 +894,8 @@ static int vpp_set_filters_internal(
s32 vpp_zoom_center_x, vpp_zoom_center_y;
u32 crop_ratio = 1;
u32 crop_left, crop_right, crop_top, crop_bottom;
u32 sar_width = 0, sar_height = 0;
bool ext_sar = false;
bool no_compress = false;
if (!input)
@@ -948,6 +954,11 @@ static int vpp_set_filters_internal(
else
vskip_step = 1;
if (super_debug)
pr_info("sar_width=%d, sar_height = %d, %d\n",
vf->sar_width, vf->sar_height,
force_use_ext_ar);
RESTART_ALL:
crop_left = video_source_crop_left / crop_ratio;
crop_right = video_source_crop_right / crop_ratio;
@@ -973,6 +984,26 @@ RESTART:
/* don't use input->wide_mode */
wide_mode = vpp_flags & VPP_FLAG_WIDEMODE_MASK;
if ((vpp_flags & VPP_FLAG_AR_MASK) == VPP_FLAG_AR_MASK) {
ext_sar = true;
sar_width = vf->sar_width;
sar_height = vf->sar_height;
} else if (force_use_ext_ar) {
ext_sar = true;
sar_width = 1;
sar_height = 1;
}
if (ext_sar && sar_width && sar_height) {
aspect_factor =
div_u64((u64)256ULL *
(u64)sar_height *
(u64)height_in,
(u32)(sar_width * width_in));
} else {
ext_sar = false;
}
/* keep 8 bits resolution for aspect conversion */
if (wide_mode == VIDEO_WIDEOPTION_4_3) {
if (vpp_flags & VPP_FLAG_PORTRAIT_MODE)
@@ -980,12 +1011,14 @@ RESTART:
else
aspect_factor = 0xc0;
wide_mode = VIDEO_WIDEOPTION_NORMAL;
ext_sar = false;
} else if (wide_mode == VIDEO_WIDEOPTION_16_9) {
if (vpp_flags & VPP_FLAG_PORTRAIT_MODE)
aspect_factor = 0x1c7;
else
aspect_factor = 0x90;
wide_mode = VIDEO_WIDEOPTION_NORMAL;
ext_sar = false;
} else if ((wide_mode >= VIDEO_WIDEOPTION_4_3_IGNORE)
&& (wide_mode <= VIDEO_WIDEOPTION_4_3_COMBINED)) {
if (aspect_factor != 0xc0)
@@ -993,6 +1026,7 @@ RESTART:
orig_aspect = aspect_factor;
screen_aspect = 0xc0;
ext_sar = false;
} else if ((wide_mode >= VIDEO_WIDEOPTION_16_9_IGNORE)
&& (wide_mode <= VIDEO_WIDEOPTION_16_9_COMBINED)) {
if (aspect_factor != 0x90)
@@ -1000,35 +1034,60 @@ RESTART:
orig_aspect = aspect_factor;
screen_aspect = 0x90;
ext_sar = false;
} else if (wide_mode == VIDEO_WIDEOPTION_CUSTOM) {
if (cur_custom_ar != 0)
if (cur_custom_ar != 0) {
aspect_factor = cur_custom_ar & 0x3ff;
ext_sar = false;
}
wide_mode = VIDEO_WIDEOPTION_NORMAL;
} else if (wide_mode == VIDEO_WIDEOPTION_AFD) {
if (aspect_factor == 0x90)
if (aspect_factor == 0x90) {
wide_mode = VIDEO_WIDEOPTION_FULL_STRETCH;
else
ext_sar = false;
} else
wide_mode = VIDEO_WIDEOPTION_NORMAL;
}
/* if use the mode ar, will disable ext ar */
if (super_debug)
pr_info("aspect_factor=%d,%d,%d,%d,%d,%d\n",
aspect_factor, w_in, height_out,
width_out, h_in, aspect_ratio_out);
width_out, h_in, aspect_ratio_out >> 2);
if ((aspect_factor == 0)
|| (aspect_factor ==
(VPP_FLAG_AR_MASK >> VPP_FLAG_AR_BITS))
|| (wide_mode == VIDEO_WIDEOPTION_FULL_STRETCH)
|| (wide_mode == VIDEO_WIDEOPTION_NONLINEAR))
|| (wide_mode == VIDEO_WIDEOPTION_NONLINEAR)) {
aspect_factor = 0x100;
else {
height_after_ratio = h_in;
} else if (ext_sar) {
/* avoid the bit length overflow */
u64 tmp = (u64)((u64)(width_out * width_in) * aspect_ratio_out);
tmp = tmp >> 2;
height_after_ratio =
div_u64((u64)256ULL *
(u64)w_in *
(u64)height_out *
(u64)sar_height *
(u64)height_in,
(u32)tmp);
height_after_ratio /= sar_height;
aspect_factor = (height_after_ratio << 8) / h_in;
} else {
/* avoid the bit length overflow */
u64 tmp = (u64)((u64)(width_out * h_in) * aspect_ratio_out);
tmp = tmp >> 2;
aspect_factor =
div_u64((unsigned long long)w_in * height_out *
(aspect_factor << 8),
width_out * h_in * aspect_ratio_out);
(aspect_factor << 8),
(u32)tmp);
height_after_ratio = (h_in * aspect_factor) >> 8;
}
height_after_ratio = (h_in * aspect_factor) >> 8;
/*
*if we have ever set a cropped display area for video layer
* (by checking video_layer_width/video_height), then
@@ -1064,17 +1123,17 @@ RESTART:
&& (wide_mode <= VIDEO_WIDEOPTION_16_9_COMBINED)
&& orig_aspect) {
if (vinfo->width && vinfo->height)
aspect_ratio_out = (vinfo->height << 8) / vinfo->width;
aspect_ratio_out = (vinfo->height << 10) / vinfo->width;
if ((video_height << 8) > (video_width * aspect_ratio_out)) {
if ((video_height << 10) > (video_width * aspect_ratio_out)) {
u32 real_video_height =
(video_width * aspect_ratio_out) >> 8;
(video_width * aspect_ratio_out) >> 10;
video_top += (video_height - real_video_height) >> 1;
video_height = real_video_height;
} else {
u32 real_video_width =
(video_height << 8) / aspect_ratio_out;
(video_height << 10) / aspect_ratio_out;
video_left += (video_width - real_video_width) >> 1;
video_width = real_video_width;

View File

@@ -411,6 +411,9 @@ struct vframe_s {
struct vframe_pic_mode_s pic_mode;
unsigned long v4l_mem_handle;
u32 sar_width;
u32 sar_height;
} /*vframe_t */;
#if 0