mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user